Simple Communication with a Java Thread
I'm looking for a very simple way to communicate with a thread in Java. Consider the following example:
boolean pass=false;
Thread simpleThread=new Thread(){
public void run(){
x=doStuff();
if (x==0) pass=true;
}
}
simpleThread.start();
I just need to know if doStuff() returned a zero or not. Of course, this is not legal in Java, but how do I implement it properly? It appears that I need some sort of Object that can be written by simpleThread and read by the开发者_如何学运维 main thread. What is that missing piece?
You may want to use Future<T>
. Instead of starting a new thread directly like this, you'd probably use an ExecutorService
, and pass it a Callable<T>
. That would return a Future<T>
for you.
You could then ask the Future<T>
at any time (from the original thread) whether it has already finished, or just block until it has finished (optionally with a timeout).
You can do the equivalent manually with a shared variable, but personally I think the Future
/Callable
approach is cleaner in the case where you're effectively computing a single (possibly complex) value on a different thread. If you need to regularly communicate with the thread (e.g. to give it more work, or see progress) then it's not as appropriate, of course.
An example using an AtomicBoolean:
final AtomicBoolean pass = new AtomicBoolean(false); //making this final means we can access it in the anonymous Thread instance
Thread simpleThread=new Thread(){
public void run(){
x=doStuff();
if (x==0) pass.set(true);
}
}
simpleThread.start();
...
pass.get(); //of course, this could return false simply because the newly spawned thread has not completed execution yet
You need to have a shared object that the two threads can see. The object must be modifiable. That is, you cannot use primitives or basic object types like String, Integer, Boolean, etc. as they are immutable.
You also need to understand and use thread synchronization.
Here is an example using a list:
List mylist = new ArrayList();
in-thread
{
synchronized( mylist )
{
mylist.add( _something_ );
}
}
in-another-thread
{
synchronized( mylist )
{
mylist.get( 0 ); // do something with result;
}
}
To illustrate @Jon's suggestion.
ExecutorService executor = ...
Future<Integer> result = executor.submit(new Callable<Integer>() {
public Integer call() {
return doStuff();
}
});
// later.
Integer x = result.get();
boolean pass = x==0;
精彩评论