我想知道如何通知另一个线程的最佳方法。例如,我有一个后台主题:
public void StartBackgroundThread(){
new Thread(new Runnable() {
@Override
public void run() {
//Do something big...
//THEN HOW TO NOTIFY MAIN THREAD?
}
}).start();
}
完成后必须通知主线程?如果有人知道如何做到这一点的最好方法我会很感激!
答案 0 :(得分:3)
纯粹基于您的问题,您可以这样做:
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();
}
}
并查看此输出
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...
答案 1 :(得分:2)
典型的答案是BlockingQueue
。 BackgroundThread
(通常称为生产者)和MainThread
(通常称为消费者)共享队列的单个实例(也许他们在实例化时获取它)。 BackgroundThread
每次收到新消息时都会queue.put(message)
调用MainThread
调用'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
BlockingQueue instance such as
ArrayBlockingQueue`。
答案 2 :(得分:1)
只需致电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();
}
答案 3 :(得分:1)
你不能“通知主线程”。
最好的方法是使用ExecutorService
,例如:
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
这些类是专门为处理异步操作而编写的,其中的所有代码都已经为您编写并且是防弹的。
如果您不想在等待时阻止主线程,请在另一个线程中等待:
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();
答案 4 :(得分:0)
通知另一个线程的一个线程不是一个好方法。最好有1个主线程,使从属线程工作。从属线程始终在运行并等待它接收工作。我建议您绘制两列并确定每个线程需要等待的确切位置。
public void run()
{
//Do something big...
synchronized(this)
{
done = true;
}
}
Java包含一些库,可以很容易地看到ExecutorService
和以下帖子
Producer/Consumer threads using a Queue