Die Klasse java.util.concurrent.FutureTask implementiert Future, Runnable und RunnableFuture und wird intern von der Java-Bibliothek verwendet, wenn wir mit submit(…) etwas beim ExecutorService absetzen. Auch wir können den Typ direkt als Wrapper um ein Callable oder Runnable nutzen, denn es gibt praktische Callback-Methoden, die wir überschreiben können, etwa done(), wenn eine Berechung fertig ist.
Dazu ein Beispiel: Ein Callable liefert den Namen des Benutzers. Ein FutureTask legt sich um dieses Callable und bekommt mit, wann das Callable fertig ist und modifiziert dann den Benutzernamen und gibt weiterhin eine Meldung aus.
Callable<String> username = () -> System.getProperty( "user.name" ); FutureTask<String> wrappedUsername = new FutureTask<>( username ) { @Override protected void done() { try { System.out.printf( "done: isDone=%s, isCancelled=%s%n", isDone(), isCancelled() ); System.out.println( "done: get=" + get() ); } catch ( InterruptedException | ExecutionException e ) { /* Ignore */ } } @Override protected void set( String v ) { System.out.println( "set: " + v ); super.set( v.toUpperCase() ); } }; ExecutorService scheduler = Executors.newCachedThreadPool(); scheduler.submit( wrappedUsername ); System.out.println( "main: " + wrappedUsername.get() ); scheduler.shutdown();
Wichtig in der Nutzung ist, nicht die Rückgabe vom submit(…) auszuwerten, was wir normalerweise machen, sondern das übergebene FutureTask zu erfragen.
Die Ausgaben vom Programm sind oft ein wenig durcheinander:
set: Christian done: isDone=true, isCancelled=false done: get=CHRISTIAN main: CHRISTIAN
Die Reihenfolge in den Aufrufen ist immer so: Der FutureTask stellt die Fertigstellung vom Callable fest und ruft set(…) auf. Anschließend done().
Ähnliche Beiträge
- CompletionService und ExecutorCompletionService
- Q&A: Wie kann man einem Thread eine bestimmte Zeit zur Ausführung geben?
- TaskExecutor und java.util.concurrent.Executor in Spring 2
- Klassen mit einer abstrakten Methode als funktionale Schnittstelle in Java 8?
- Klassen mit einer abstrakten Methode als funktionale Schnittstelle?