2015-07-07 11 views
6

Derzeit verwenden wir Threads in unserer Anwendung (Java). Aber es werden einige 1000 (oder mehr) Threads gleichzeitig erstellt. Diese Threads sollten die Daten verarbeiten und in db speichern.Was könnte die beste Alternative zu Multi-Threading sein?

Dies verbraucht mehr Speicher und E/A.

Was könnte die beste Alternative dafür sein ?. Skalierbarkeit, Konsistenz und Leistung sind die Hauptanforderungen.

+6

Das grundlegende Missverständnis über Threads ist, dass je mehr desto besser. Dies ist im Allgemeinen nicht wahr, normalerweise ist das Gegenteil das, was Sie wollen: so wenige Threads wie Sie durchkommen können, nicht wesentlich mehr als die Anzahl der CPUs, die Sie haben. Selbst wenn Ihr Prozess E/A-gebunden ist und die meisten Ihrer Threads auf I/O warten, können Sie mit mehr Threads möglicherweise nichts kaufen, da dies die Systeme, mit denen Sie E/A arbeiten, verlangsamen kann. – biziclop

+4

Verwenden Sie bereits einen Thread Pool? Ich hoffe, du erschaffst nicht direkt ein paar tausend Threads. –

+1

Das heißt, Ihr Problem ist viel zu allgemein, um eine gute Antwort zu bekommen. Akka und Hadoop sind zwei sehr unterschiedliche mögliche Antworten, die zum Beispiel passen oder nicht passen können.Es ist jedoch auch möglich, dass die Verwendung eines Thread-Pools mit entsprechender Größe ausreicht. – biziclop

Antwort

17

Haben Sie versucht thread pools? Ein Thread-Pool besteht aus einer angemessenen Anzahl von Threads (genug, um alle Prozessoren zu verwenden, aber nicht viel mehr) und wiederverwendet Threads (wieder Overhead reduzieren), um eine große Anzahl von Aufgaben gleichzeitig auszuführen.

Hier ist ein kleines Beispiel Ihnen eine Idee

ExecutorService executor = Executors.newFixedThreadPool(5); 
Runnable job = new Runnable() { 
    public void run() { 
     // do some work 
    } 
} 
executor.execute(job); 

geben Wenn Sie die ScheduledThreadPoolExecutor schauen, werden Sie eine Menge von Funktionen zum Ausführen und Planen von Jobs finden.

+0

Wenn ich mit Thread-Pool der Größe 100 gehe, wird es 100 Db-Verbindungen erstellt, die genauso wie keine Verbindungen ohne Thread-Pool erstellt werden. Kannst du bitte irgendeinen Weg vorschlagen, um db-Verbindungen zu erstellen und sie von allen Threads verwenden zu lassen? –

+0

Scheint mir so, als ob du eine neue Frage öffnen solltest und mehr Details darüber, was du machst und warum. In der Zwischenzeit sollte der Thread-Pool in den meisten Fällen höchstens doppelt so viele Threads aufweisen wie der Server über Kerne. Weniger, wenn Ihre Datenbank auf demselben Server ausgeführt wird. – Cephalopod

8

Verwenden Sie einen Thread-Pool. Auf diese Weise können Sie eine Anzahl von Threads definieren, die ausgeführt werden sollen. Jede neue Aufgabe wird in eine Warteschlange gestellt und wartet dort, bis ein Thread mit seiner alten Aufgabe fertig ist und somit frei ist, eine neue Aufgabe zu bearbeiten.

Dies ist skalierbar, da Sie festlegen können, wie viele Threads ausgeführt werden sollen. Sie können wenige Threads auf einem Gerät mit wenigen Prozessorkernen auswählen, um Speicherplatz zu sparen und den Synchronisationsaufwand zu reduzieren, oder viele Threads auf einem Gerät mit vielen Kernen. So z.B. Wenn Sie dies auf einem Gerät mit 4 Kernen und Hyperthreading ausführen, wählen Sie 8 Threads, wenn Sie es auf einem Gerät mit 48 Hardware-Threads ausführen, dann wählen Sie 48 Threads.

Die Leistung ist im Allgemeinen besser als das Starten eines neuen Threads für jede Aufgabe, da das Starten und Löschen von Threads ziemlich viel Aufwand verursacht. Threadpools verwenden Threads neu und haben somit keinen Overhead.

Es ist auch konsistent, da es eine Threadpool-Implementierung in der Java-Standardbibliothek gibt.

+1

Als eine Randbemerkung ist Thread-Pool-Sizing schwierig, und während die Faustregel der Verwendung genau so viele Threads wie Sie parallel ausführen können, ein guter Ausgangspunkt ist, sollten Sie Ihre Anwendung überwachen, um das Maximum daraus zu ziehen und die Dinge entsprechend anpassen. Wenn Sie beispielsweise viel I/O verwenden, ist ein etwas größerer Pool möglicherweise besser, wenn Sie einen parallelen GC verwenden und der Overhead zu groß ist, lassen Sie einige Kerne für den GC und so weiter. – biziclop

+0

@Dakkaron, danke für den Vorschlag. Aber meine Zweifel ist, wenn ich 48 Threads auf einmal nehme, dann wird es nicht viel Zeit brauchen, um meine 1000 Threads laufen zu lassen ?? –

+0

wäre es schön, wenn die Pool-Parameter während des Laufens geändert werden könnten – Skaperen

12

Versuchen Sie einen Blick auf die Actor model.

Das Schauspieler Modell ein gleichzeitiges Programmiermodell ist, in dem die Arbeitsbelastung zwischen Einheiten parallel ausgeführt verteilt wird, genannt Akteure.

Es ist ein Modell, in dem kein gemeinsamer Zustand ist, Schauspieler sind isoliert und Informationen können in Form von Nachrichten fließen.

Die Spieler erhalten diese Nachrichten und können nur reagieren, indem sie die Daten in der Nachricht manipulieren (Daten verarbeiten oder verarbeiten), eine Nachricht an andere Spieler senden oder neue Akteure erstellen.

Dieses Modell ist eine Abstraktion auf hoher Ebene über Mutex-Locks und Threads, die die Komplexität für den Entwickler beseitigt und vor allem für den Aufbau von hochverfügbaren und konkurrierenden Telekommunikationssystemen entwickelt wurde, von Ericsson 1973 unter Erlang.

Actors sind sehr leichte gleichzeitige Entitäten.Sie verarbeiten Nachrichten asynchron mit einer ereignisgesteuerten Empfangsschleife. Mustervergleich mit Nachrichten ist eine bequeme Möglichkeit, das Verhalten eines Akteurs auszudrücken. Sie erhöhen das Abstraktionsniveau und erleichtern das Schreiben, Testen, Verstehen und Verwalten von gleichzeitigen und/oder verteilten Systemen. Sie können sich auf den Arbeitsablauf - wie die Nachrichten im System fließen - konzentrieren, anstatt auf Low-Level-Primitive wie Threads, Locks und Socket-IO.

In Java/Scala können Sie die Akka framework finden, die auf diesem Akteurmodell basiert basiert.

+1

Aktoren neigen dazu, deutlich langsamer als reine Fäden zu sein. Vielleicht nicht wichtig in vielen Kontexten. Aber wenn rohe Geschwindigkeit kritisch ist, ist es gut, daran zu denken. Sie neigen auch dazu, ein wenig auf der ausführlichen und IMHO schwieriger zu beheben. – javadba

+0

Aber wie wäre es mit seiner Verwendung in Spark, sagen wir? Wenn ich mich nicht irre, verwendet Spark das Schauspielermodell. – eliasah

+2

Spark führt nicht viele viele Threads pro jvm. Mit "vielen" meine ich hunderte oder mehr. Auf dieser Ebene zeigt sich der Leistungsunterschied wirklich. – javadba

5

Ich denke, Sie brauchen keine Alternative zu Multi-Threading, nur eine effizientere Thread-Implementierung.

QuasarfügtFasern (dh leichte Fäden) der JVM, von denen Sie sogar Millionen statt ein paar hundert erstellen können, so können Sie ohne auf den Faden Abstraktion die gleiche Leistung von Asynchron-Frameworks erhalten und regelmäßige imperative Kontrollflusskonstrukte (Sequenz, Schleifen usw.), die in der Sprache verfügbar sind.

Es vereint auch JVM/JDK Threads und seine Fasern unter einem gemeinsamen Strang Schnittstelle, so dass sie nahtlos zusammenarbeiten können, und stellt eine Portierung von java.util.concurrent zu diesem einheitlichen Konzept. Dies bedeutet auch, dass Ihr Portierungsaufwand minimal ist (falls vorhanden).

Oben Stränge (entweder Fasern oder regelmäßige Themen) Quasar bietet auch vollwertiges Erlang-Stil Schauspieler (siehe here für einen Vergleich mit Akka), Sperrung Go-ähnliche Kanäle und Datenflussprogrammierung, Sie können also das parallele Programmierparadigma wählen, das Ihren Fähigkeiten und Bedürfnissen am besten entspricht, ohne dass Sie dazu gezwungen werden.

Es bietet auch Bindungen für beliebte und Standardtechnologien (als Teil des Comsat Projekt), so können Sie Ihren Code Vermögen zu bewahren, da die Portierung Aufwand minimal sein (falls vorhanden). Aus dem gleichen Grund können Sie sich auch einfach abmelden, wenn Sie möchten.

Derzeit Quasar hat Bindungen für Java 7 und , Clojure unter dem Pulsar Projekt und JetBrains' Kotlin. Basierend auf der JVM-Bytecode-Instrumentierung kann Quasar mit jeder JVM-Sprache arbeiten, wenn ein Integrationsmodul vorhanden ist, und es bietet Tools zum Erstellen zusätzlicher.

Beginnend mit Java9 erfolgt die Instrumentierung automatisch und es werden keine Integrationsmodule mehr benötigt.

+0

Wie benutzt man Fasern ?? irgendein Tutorial ?? –

+0

Die oben verlinkten Dokumente von Quasar, Pulsar und Comsat sind ziemlich umfangreich und gut als Tutorials; Sie verlinken auch einen Quasar Maven Archetyp und seine entsprechende Gradle Vorlage, einen Comsat Maven Archetyp und seine entsprechende Gradle Vorlage, Comsat Beispiele, eine Comsat Ring Leiningen Vorlage, Quasar-Aktien portiert von Akka/Play und ein Comsat-jOOQ Beispiel. Viele Informationen und Tutorials finden Sie im [blog] (http://blog.paralleluniverse.co), wie zum Beispiel ein Screencast und andere. Die Google Quasar/Pulsar und Comsat Foren sind ebenfalls eine gute Quelle. – circlespainter

+2

Es sieht so aus, als ob dies eine Technologie ist, die Ihr Arbeitgeber entwickelt hat. Sie sollten Ihre Zugehörigkeit wahrscheinlich erklären: http://meta.stackexchange.com/questions/57497/limits-for-self-promotion-in-answers#59302 –

Verwandte Themen