Reputation: 23
I want to submit some SwingWorkers to ExecutorService, and get Futures from them to see later if they have finished and what the results are.
However, ExecutorService's submit method will only return a Future<?>
when I want a Future<Integer>
.
So, questions:
Am I extending SwingWorker correctly? The first generic type is what is returned by get() on the SwingWorker, so I guessed it is also what the Future get() method will return.
Is SwingWorker the wrong thing to use? (Trying to read about this problem, I see mostly people submitting Callables to ExecutorService) If so, what would be better and what is the best way to convert it? (my actual extension of SwingWorker is more complex than this example, and updates the GUI etc). I started trying to implement Callable in a new class but I am not sure how to implement the publish/process process (no pun intended).
Some example code that reproduces the problem:
The SwingWorker extension
import javax.swing.SwingWorker;
public class Worker extends SwingWorker<Integer, Void>
{
public Worker ()
{
}
@Override
public Integer doInBackground()
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 1;
}
@Override
public void done()
{
System.out.println("done\n");
}
}
Main - the executor.submit(w)
part gives a compile error:
Type mismatch: cannot convert from Future<capture#1-of ?> to Future<Integer>
And asks if I'd like to change future to be of type Future<?>
or cast the executor.submit(w)
part to Future<Integer>
.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main
{
public static void main (String[] args)
{
ExecutorService executor = Executors.newFixedThreadPool(2);
Worker w = new Worker();
Future<Integer> future = executor.submit(w);
}
}
Upvotes: 1
Views: 2629
Reputation: 205785
You may want to use this variation of submit()
to make the result type explicit:
<T> Future<T> submit(Runnable task, T result)
As discussed here, submit()
doesn't do anything with result
. "When the task successfully completes, calling future.get()
will return the result you passed in." Note that the type of result
matches that of the SwingWorker
result type, T
.
Code:
Integer i = 42;
Future<Integer> future = executor.submit(w, i);
System.out.println(future.get());
Console:
42
done
In the larger context of your actual program, you'll want to publish()
intermediate results and process()
them on the EDT.
Upvotes: 2