2017-10-26 3 views
1

Meine Klasse erweitert DownloadTaskjavafx.concurrent.Task<Boolean> zu einem ExecutorServiceZukunft <T> nicht mit Klasse-kompatibel, der Aufgabe <T> in Java Executor Dienst

Nach dem Absenden meiner Aufgabe erstreckt, versuche ich Future<Boolean> das Ergebnis in eine Variable vom Typ zuzuordnen. Die IDE warnt mich jedoch, dass mein instanziiertes Objekt den generischen Typ <capture<?>> hat und ich weiß nicht warum. Meine Klasse

DownloadTask:

import javafx.concurrent.Task; 

private class DownloadTask extends Task<Boolean>{ 
    public DownloadTask() {} 

    @Override 
    protected Boolean call() throws Exception { 
     return true; 
    } 
} 

Wie ich den Thread-Pool verwalten:

ExecutorService executor = Executors.newFixedThreadPool(10); 
ArrayList<Future<Boolean>> resultList = new ArrayList<>(); 

for (ScheduleRow scheduleRow : queArray) { 
    DownloadTask downloadTask = new DownloadTask(); 

    Future<Boolean> result = executor.submit(downloadTask); //incompatible types 

    resultList.add(result); 
} 

executor.shutdown(); 
+0

Was ist die 'Task' Klasse hier? –

+0

Vermutlich ist das Problem, dass 'Task implementiert Runnable', nicht 'Callable ', so dass es eine 'Zukunft ' zurückgibt. –

+0

@AndyTurner Hallo. Ich bin mir nicht sicher, ob ich das verstehe. Nach dem, was ich gelesen habe, kann ich eine Aufgabe verwenden und sie aufrufen, indem ich sie dem Executor vorlege. Ich bin neu, also verstehe ich es kaum. –

Antwort

1

Kurze Antwort

diese Warnung zu beheben, Sie könnten nur Typen Info hinzufügen Typinferenz aktivieren:

Future<Boolean> result = executor.submit(downloadTask, true); 

jedoch darüber im Klaren sein, für die result Variable, die Future ‚s get Methode wird die angegebene True nach erfolgreichem Abschluss zurückgeben, da die DownloadTask alsinterpretiert wird, die kein Ergebnis liefert. Als Mike Strobel sagt, ist ein besserer Weg, das richtige Ergebnis aus den DownloadTask selbst zu bekommen, da es auch ein Future<Boolean> ist:

executor.submit(downloadTask); 
resultList.add(downloadTask); 

Lange Antwort

wie Andy Turner sagte, die geerbte typye für javafx.concurrent.Task ist Runnable (seit es erweitert FutureTask Implementierung RunnableFuture).

diesen Passing zur Future<?> submit(Runnable task) Methode der ExecutorService ein Future<?> Ergebnis liefern und die IDE werden diese fiesen Future<capture<?>> werfen.

Allerdings brauchen Sie nicht eine javafx spezifische ExecutorService, die java.util.concurrent.ExecutorService funktioniert gut, da DownloadTask eine Unterklasse von FutureTask ist.

Um die Inferenz zu korrigieren, können Sie die generische <T> Future<T> submit(Runnable task, T result) Methode der java.util.concurrent.ExecutorService verwenden.Da es sich um eine einfache Boolesche ist können Sie auf Autoboxing verlassen:

Future<Boolean> result = executor.submit(downloadTask, true); 

Das Problem ist, dass für die result Variable, die Future ‚s Methode bekommen die gegebene wahr nach erfolgreichem Abschluss zurückzukehren. In Ihrem Beispiel würde die get Methode auf dem resultierenden Future immer null zurückgeben. Das liegt daran, dass es als Runnable interpretiert wird, das kein Ergebnis liefert. Als Mike Strobel sagte, ist ein besserer Weg, das richtige Ergebnis aus dem DownloadTask selbst zu bekommen, da es auch eine Zukunft ist:

executor.submit(downloadTask); 
resultList.add(downloadTask); 
0

Nach dem Javadoc von javafx.concurrent.Task, Task implementiert Runnable, nicht Callable<T>.

Wenn Sie es also an eine ExecutorService senden, wird es wie etwas behandelt, das keinen Wert zurückgibt, so dass die resultierende Zukunft eine Future<?> ist.

Entweder einen javafx-spezifischen ExecutorService verwenden (keine Ahnung, ob es einen speziell für Task gibt); Oder lassen Sie Ihre Klasse stattdessen Callable<Boolean> implementieren.

0

Sie brauchen nicht wirklich etwas mit dem Ergebnis der submit zu tun; Ihr DownloadTask ist bereits ein Future<Boolean>, und wenn es ausgeführt wird, wird es sein eigenes Ergebnis festlegen. Die Future<?>, die von submit zurückgegeben wird, ist sowieso nicht in der Lage, das Ergebnis Ihrer Aufgabe weiterzuleiten, da sie es einfach als Runnable sieht, die keinen Wert erzeugt.

Ganz einfach ändern:

Future<Boolean> result = executor.submit(downloadTask); 
resultList.add(result); 

Um dies:

executor.submit(downloadTask); 
resultList.add(downloadTask); 
Verwandte Themen