2017-06-04 4 views
0

Ich schreibe eine Multi-Thread-Anwendung, wo ich die Situation habe, dass ich bestimmte Bibliothek bezogenen Methoden, die nur laufen auf demmain-thread sein. Zur Zeit leite ich eine einfache, selbst geschriebene Lösung, die eine Warteschlange für Aufgaben abhört und sie dann seriell ausführt.Java Testamentsvollstrecker Modell, das nur Aufgaben ausgeführt ermöglicht Thread auf Instanziieren

Dies funktioniert soweit, obwohl es hässlich wird, wenn ich Rückgabewerte usw. brauche Ich löse derzeit den C-Weg, indem ich Datenstrukturen mit den Tasks weiterleite und dann eine Busy-Loop überprüfe, ob die Struktur auf den Standort der Methode geschrieben wurde, die eine Task in die Warteschlange stellt sauberste Lösung, und während es funktioniert, hoffte ich, einen besseren Weg zu finden.

Q: Gibt es etwas in der JDK oder in einer einzelne spezialisierte Bibliothek, die das tut, was ich brauche? Oder gibt es ein Programmiermuster, das meine Bedürfnisse sauber und strukturiert anspricht?

+0

Warum nicht einfach Futures zu Ihrer bestehenden Architektur hinzufügen? Übergeben Sie eine 'CompleableFuture' anstelle dieser abrufbezogenen Struktur. Es kann dann vom cilent mit der Methode 'get()' abgewartet werden (oder abgefragt werden). –

+0

@RomanPuchkovskiy Ich denke, ich würde nicht wissen, wo ich anfangen soll, den zukünftigen Mechanismus zu implementieren. Vielleicht denke ich zu weit ..... es sei denn, ich hatte gerade die geniale Idee, einfach einen Semaphor als eine Art Warte-Sperre für die get-Methode zu verwenden:/ –

+0

Dem vorgeschlagenen Ansatz eine Illustration hinzugefügt –

Antwort

1

Eine mögliche Lösung mit CompletableFuture:

class Job<T> { 
    private final Supplier<T> computation; 
    private final CompletableFuture<T> future; 

    Job(Supplier<T> computation, CompletableFuture<T> future) { 
     this.future = future; 
     this.computation = computation; 
    } 

    public Supplier<T> getComputation() { 
     return computation; 
    } 

    public CompletableFuture<T> getFuture() { 
     return future; 
    } 
} 

public void client() { 
    // on the client: 
    CompletableFuture<String> future = new CompletableFuture<>(); 
    Supplier<String> computation =() -> "Here I am!"; 

    enqueue(new Job<>(computation, future)); 

    String resultString = future.get(); 
} 

public <T> void server(Job<T> job) { 
    // on the server; job is taken from the queue 
    CompletableFuture<T> future = job.getFuture(); 
    future.complete(job.getComputation().get()); 
} 

Hier auf dem Client, future.get() wird unendlich warten, bis das Ergebnis vorliegt. Es gibt auch ein anderes Formular:

future.get(1, TimeUnit.MINUTES) 

würde nur eine Minute warten und dann zurückkehren. Dies kann für die Abfrage verwendet werden.

+0

Dies ist wild . Ich wusste nicht, dass es Futures gab. Nur das Interface gesehen. –

0

Lassen Sie Ihre Haupt-Thread Rolle eines Executor spielt:

static ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10); 
public static void main(String... args) { 
    // initialization... 
    for (;;) { 
     queue.take().run(); 
    } 
} 

Jedes Mal, wenn Sie eine Aufgabe auf dem Haupt-Thread ausgeführt werden müssen, setzen Sie es in die Warteschlange:

queue.add(()->methodCall(1,2,3)); 
0

Ich bin nicht Sicher, wie Sie den Hauptthread zeitlich schneiden, aber was Sie sagen, ist, dass Sie einige Jobs nacheinander mit mehreren Threads und anderen Jobs im Hauptthread ausführen möchten.

Die einfachste Antwort wäre, zwei verschiedene Arbeitswarteschlangen zu verwenden - eine, die von mehreren Threads bedient wird und eine, die nur vom Hauptthread bedient wird.

Dadurch würden beide Warteschlangen einfacher zu verstehen und zu verwenden sein.

Außerdem sollten Jobs, die auf einer der beiden Warteschlangen ausgeführt werden, eine Schnittstelle implementieren, die eine Methode erfordert, die einen Verweis auf die resultierenden Daten zurückgibt. Dies können die tatsächlichen Ergebnisse oder ein Dateiname oder ein an die Datei angehängter Eingabestream sein die Ergebnisse.

Verwandte Themen