Reputation: 7018
I want to know the best way how to notify another thread. For example, I have a background thread:
public void StartBackgroundThread(){
new Thread(new Runnable() {
@Override
public void run() {
//Do something big...
//THEN HOW TO NOTIFY MAIN THREAD?
}
}).start();
}
When it finished it has to notify main thread? If somebody knows the best way how to do this I'll appreciate it!
Upvotes: 8
Views: 14290
Reputation: 425033
You can't "notify the main thread".
The best approach is to use an ExecutorService
, like this for example:
import java.util.concurrent.*;
// in main thread
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(new Runnable() {
@Override
public void run() {
//Do something big...
}
});
future.get(); // blocks until the Runnable finishes
The classes are written specially to deal with asynchronous operations, and all the code in there is already written for you and bullet-proof.
If you don't want to block the main thread while waiting, wait within another thread:
final Future<?> future = executorService.submit(new Runnable() {
@Override
public void run() {
//Do something big...
}
});
new Thread(new Runnable() {
@Override
public void run() {
future.get(); // blocks until the other Runnable finishes
// Do something after the other runnable completes
}
}).start();
Upvotes: 2
Reputation: 535
Purely based on your question you could do this:
public class test
{
Object syncObj = new Object();
public static void main(String args[])
{
new test();
}
public test()
{
startBackgroundThread();
System.out.println("Main thread waiting...");
try
{
synchronized(syncObj)
{
syncObj.wait();
}
}
catch(InterruptedException ie) { }
System.out.println("Main thread exiting...");
}
public void startBackgroundThread()
{
(new Thread(new Runnable()
{
@Override
public void run()
{
//Do something big...
System.out.println("Background Thread doing something big...");
//THEN HOW TO NOTIFY MAIN THREAD?
synchronized(syncObj)
{
System.out.println("Background Thread notifing...");
syncObj.notify();
}
System.out.println("Background Thread exiting...");
}
})).start();
}
}
and see this output
PS C:\Users\java> javac test.java
PS C:\Users\java> java test
Main thread waiting...
Background Thread doing something big...
Background Thread notifing...
Background Thread exiting...
Main thread exiting...
Upvotes: 4
Reputation: 734
The typical answer is a BlockingQueue
. Both BackgroundThread
(often called the Producer) and MainThread
(often called the Consumer) share a single instance of the queue (perhaps they get it when they are instantiated). BackgroundThread
calls queue.put(message)
each time it has a new message and MainThread
calls 'queue.take()which will block until there's a message to receive. You can get fancy with timeouts and peeking but typically people want a
BlockingQueueinstance such as
ArrayBlockingQueue`.
Upvotes: 4
Reputation: 8028
One thread notifying another thread is not a good way to do it. Its better to have 1 master thread that gives the slave thread work. The slave thread is always running and waits until it receives work. I recommend that you draw two columns and determine exactly where each thread needs to wait.
public void run()
{
//Do something big...
synchronized(this)
{
done = true;
}
}
Java includes libraries that make this really easy see ExecutorService
and the following post
Producer/Consumer threads using a Queue
Upvotes: 0
Reputation: 127
Just call notify()
public void run() {
try {
while ( true ) {
putMessage();
sleep( 1000 );
}
}
catch( InterruptedException e ) { }
}
private synchronized void putMessage() throws InterruptedException {
while ( messages.size() == MAXQUEUE )
wait();
messages.addElement( new java.util.Date().toString() );
notify();
}
Upvotes: 1