2011-05-27 60 views
6

比方说,我想创建一个基本上无限地运行线程的对象。我希望线程能够在没有需要的情况下进入睡眠状态,但是当需要完成特定的工作时,它会唤醒线程 - 完成工作并重新进入睡眠状态。我也希望这些工作能够排队并按照他们到达的顺序执行。在cocoa/objective c中,有一个NSOperationQueue。我不知道java是否有类似的东西。Java:如何根据需要唤醒线程?

您认为如何?

回答

3

我会用一个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

您可以使用一些BlockingQueue

当您从队列中读取(在线程中)时,您将获得下一个项目,或者如果它是空的 - 请等到收到一个项目。

这实际上并不是在睡觉线程,而是使用队列的阻塞属性。例如:

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

上面的代码是一个Runnable - 您可以使用一个ExecutorService开始运行的,或者用Thread

课程的qeueue外部设置了老式的方法,和被填充(再次外部)入局项目。

3

我认为BlockingQueueThreadPoolExecutor的组合可以满足您的需求。或者,如果您在Java EE应用服务器上部署,则可以使用JMS和消息驱动的Bean。

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