简体   繁体   English

如何通知另一个线程

[英]How to notify another thread

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! 如果有人知道如何做到这一点的最好方法我会很感激!

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...

The typical answer is a BlockingQueue . 典型的答案是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 (通常称为Producer)和MainThread (通常称为Consumer)共享队列的单个实例(可能在实例化时获取它)。 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 BackgroundThread每次有queue.put(message)调用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 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`. 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`。

Just call notify() 只需调用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(); 
} 

You can't "notify the main thread". 你不能“通知主线程”。

The best approach is to use an ExecutorService , like this for example: 最好的方法是使用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

The classes are written specially to deal with asynchronous operations, and all the code in there is already written for you and bullet-proof. 这些类是专门为处理异步操作而编写的,其中的所有代码都已经为您编写并且是防弹的。

Edit 编辑

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();

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. 最好有1个主线程,使从属线程工作。 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 Java包含的库可以让我们很容易地看到ExecutorService以及使用Queue的后续生产者/消费者线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM