如何通知另一个线程

时间:2013-01-15 01:14:32

标签: java multithreading

我想知道如何通知另一个线程的最佳方法。例如,我有一个后台主题:

public void StartBackgroundThread(){
new Thread(new Runnable() {         
        @Override
        public void run() {
            //Do something big...
            //THEN HOW TO NOTIFY MAIN THREAD?
        }
    }).start();
}

完成后必须通知主线程?如果有人知道如何做到这一点的最好方法我会很感激!

5 个答案:

答案 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)

典型的答案是BlockingQueueBackgroundThread(通常称为生产者)和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