2017-04-07 7 views
2

Ich möchte einige Aufgaben in einer serialisierten Weise ausführen. Die typische Lösung hierfür besteht darin, einen Task zu erstellen und Aufgaben auf diesem auszuführen.Java: single-threaded Unter-Executor in einem anderen Multithread Executor

Allerdings habe ich bereits einen Thread-Pool, der Multi-Threaded ist.

Gibt es eine einfache Möglichkeit, einen Sub-Executor abzuleiten, der sich wie ein Singlethread-Thread verhält (wie: nur eine Task gleichzeitig ausführt), aber einen anderen (möglicherweise nicht single-threaded) Executor verwendet "Backend" anstatt einen brandneuen OS-Thread zu erstellen?

Es gibt mehrere Anwendungsfälle dafür, warum wir wollen, würde dies tun:

  • die App vielleicht schon einen Thread-Pool haben für z.B. Hintergrundaufgaben, mit eine festgelegte Priorität usw., die wir gerne wiederverwenden würden.
  • In ähnlicher Weise könnte man in einem Exekutor übergeben, die nicht nur ein einfachen Thread-Pool (zB Ausführungs Aufschieben für späte Messung der Ausführungszeit etc.)
    • eine Teilmenge davon in MoreExecutors.directExecutor Passing() für Testen (damit zB Futures sofort auflösen).

EDIT: hinzugefügt, um die obigen Beispiele

+2

Können Sie einen Taskcode eingeben, den Sie in einem Thread ausführen möchten? Ich denke, das Ausführen einer Aufgabe in einem einzelnen Thread würde von der Aufgabe selbst entschieden werden. Wenn Sie nicht versuchen, etwas innerhalb der Aufgabe in einem anderen Thread zu tun, wird es nur im selben Thread ausgeführt. –

+0

Ich stimme Vijendra zu - Ihre Frage ist interessant, aber um mehr hilfreiches Feedback zu geben, könnte uns ein bisschen Code helfen. – GhostCat

Antwort

2

Ein solcher zero-threaded Executor heißt SerialExecutor und ist in der Java-Dokumentation zu java.util.concurrent.Executor beschrieben.Es hat jedoch einen kleinen Nachteil: Für jedes übergebene Runnable wird ein Wrapper-Objekt erstellt. My own implementation erstellt keine zusätzlichen Objekte.

+0

cool, danke! Es ist etwas überraschend, dass sie eine nützliche Klasse in den Java-_docs_ anstelle von, na ja, tatsächlichem Code ... stellen würden. Ich frage mich, wie oft es von dort kopiert wurde. – Latanius

0

Mein Vorschlag: gehen Sie nicht dorthin.

Das macht aus praktischer Sicht einfach keinen Sinn: Sie sind bereit, eine kompliziertere Lösung für ein Problem einzuführen ... das ist eigentlich kein Problem.

Sie sehen: wenn dieser "andere" Multi-Thread-Dienst im Leerlauf läuft ... warum haben Sie das an erster Stelle? Wenn Sie OS-Threads speichern möchten; Warum benutzt du diesen Multithread-Dienst, der aus Mangel an Arbeit langweilig zu sein scheint?

Aber wenn es nicht im Leerlauf ist - wie denken Sie, können Sie Aufgaben von diesem "single-thread" Dienst "phasen"? In einer konsistenten Weise?

Und ja, Threads sind nicht gerade billig; Aber wenn Sie wirklich an einem Punkt sind, an dem das Speichern dieses einzelnen Threads für Sie ein Problem löst ... gehen Sie einen Absatz zurück und fragen Sie sich noch einmal: Was ist mit diesem inaktiven Multi-Threading-Dienst?

Also, vielleicht gibt es eine technische Möglichkeit, Ihre Idee umzusetzen; aber ernsthaft; Meine Antwort ist - mit dem, was Sie schon bekommen:

Executor executor = Executors.newSingleThreadedExecutor(); 

Und Zugabe auf der anderen Antwort/Kommentar: ja der Schauspieler Modell hier helfen könnte; Konzepte zu vermischen ist jedoch selten eine gute Idee. Wenn der Actor-Ansatz gut in Ihr Gesamtmodell passt (vielleicht gibt es gute Möglichkeiten, mehr Teile Ihres Codes zu ändern, um davon Gebrauch zu machen) - gut. Aber wenn nicht; seien Sie vorsichtig beim Hinzufügen dieses zusätzlichen Teils der begrifflichen Komplexität, nur um ein Problem zu lösen ... was wie gesagt; ist vielleicht gar kein echtes Problem.

+0

Welches Thema der Starter will, ist eigentlich ein 'Actor', der Nachrichten vom Typ' Runnable' akzeptiert und sie durch Aufruf von 'message.run()' verarbeitet. Das Konzept von Actor ist nicht so kompliziert, intuitiv genug und wird in den letzten 40 Jahren erfolgreich entwickelt. Siehe Details unter https://github.com/rfqu/CodeSamples/tree/master/src/simpleactor –

+0

Ich mag Ihre kurze Antwort; also aufgewertet; aber nachdem ich einige Zeit nachgedacht hatte, beschloss ich, meine Antwort auch zu behalten. Alles hängt davon ab, "wie viel von einem Problem" das OP wirklich hat. Wir machen Dinge nicht, weil wir können, sondern weil sie etwas Sinn machen und verbessern, das es wert ist, verbessert zu werden. Und eine Lösung, die heute mit zwei Pools funktioniert; Was gewinnen Sie durch eine größere Überarbeitung, um stattdessen einen Pool zu nutzen? (vielleicht viel, aber das hängt wirklich davon ab, was genau er macht und in welchem ​​Umfang das passiert). – GhostCat

+0

Danke für die Antwort! Ich stimme zu, dass es für die meisten Fälle eine gute Idee ist und OS-Threads schließlich nicht so teuer sind. Es könnte jedoch noch seltsamere Fälle geben, in denen es nützlich sein könnte. Siehe die Beispiele, die ich oben hinzugefügt habe. – Latanius

Verwandte Themen