Java:如何按需唤醒线程?

时间:2011-05-27 10:29:10

标签: java multithreading

假设我想创建一个基本上无限运行线程的对象。我希望线程在不需要他的情况下休眠,但是当需要完成某项工作时,它会唤醒线程 - 完成工作并重新开始睡眠。我还希望将作业排队并按照它们到达的顺序执行。在cocoa / objective c中有一个NSOperationQueue。我想知道java是否有类似的东西。

您怎么看?

5 个答案:

答案 0 :(得分:4)

我认为BlockingQueueThreadPoolExecutor的组合可以满足您的需求。

或者,如果在Java EE应用服务器上部署,则可以使用JMS和消息驱动的bean。

答案 1 :(得分:4)

我会使用像

这样的ExecutorService
private final ExecutorService executor = Executors.newSingleThreadExecutor();

public void task(final int arg) {
    executor.execute(new Runnable() {
        @Override
        public void run() {
            // perform task using `arg`
        }
    });
}

这有一个内置线程,在添加任务时唤醒,在没有任务时休眠,为队列任务阻塞队列。

答案 2 :(得分:3)

您可以使用一些BlockingQueue

当你从队列中读取(在线程中)时,你要么得到下一个项目,要么是空的 - 等到收到一个。

这实际上并没有让线程休眠,而是使用队列的阻塞属性。例如:

private BlockingQueue queue;
@Override
public void run() {
    while(true) {
        handle(queue.poll());
    }
}

以上代码位于Runnable中 - 您可以使用ExecutorService启动可运行,或使用Thread

的老式方式

队列当然是在外部设置的,并且与传入的项目一起填充(再次在外部)。

答案 3 :(得分:1)

您可以在java.util.concurrent库中找到所需内容 - 它是比Thread更高级别的API。看看http://www.ibm.com/developerworks/java/library/j-jtp1126/index.html

答案 4 :(得分:0)

由于你想要类似于NSOperationQueue的东西,我再次使用Java的ExecutorService。我不确定ExecutorService是否轮询或等待中断。如果你需要更多的控制,那么就有这些低级别的中断驱动方法:

class InterruptDriven {
   private final ReentrantLock lock = new ReentrantLock(true);
   private final Condition asynchronousTrigger = lock.newCondition();
   private AtomicBoolean poisoned = new AtomicBoolean(false);

   public void interrupt() {
      final ReentrantLock lock = this.lock;
      try {
         lock.lockInterruptibly();
         asynchronousTrigger.signal();
      } catch (InterruptedException ex) {
         ....
      } finally {
         lock.unlock();
      }
   }
   public void workerWait(){
      final ReentrantLock lock = this.lock;
      lock.lockInterruptibly();
      try {
         try {
            if (!poisoned.get()) {
               asynchronousTrigger.await();
               ... do some work here ...
            }
         } catch (InterruptedException ie) {
            ...
         }
      } finally {
         lock.unlock();
      }
   }