比方说,我想创建一个基本上无限地运行线程的对象。我希望线程能够在没有需要的情况下进入睡眠状态,但是当需要完成特定的工作时,它会唤醒线程 - 完成工作并重新进入睡眠状态。我也希望这些工作能够排队并按照他们到达的顺序执行。在cocoa/objective c中,有一个NSOperationQueue。我不知道java是否有类似的东西。Java:如何根据需要唤醒线程?
您认为如何?
比方说,我想创建一个基本上无限地运行线程的对象。我希望线程能够在没有需要的情况下进入睡眠状态,但是当需要完成特定的工作时,它会唤醒线程 - 完成工作并重新进入睡眠状态。我也希望这些工作能够排队并按照他们到达的顺序执行。在cocoa/objective c中,有一个NSOperationQueue。我不知道java是否有类似的东西。Java:如何根据需要唤醒线程?
您认为如何?
我会用一个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`
}
});
}
这有一个内置的线程时添加一个任务,它唤醒和休眠的时候没有任务离开,一个阻塞队列,队列任务。
您可以使用一些BlockingQueue
。
当您从队列中读取(在线程中)时,您将获得下一个项目,或者如果它是空的 - 请等到收到一个项目。
这实际上并不是在睡觉线程,而是使用队列的阻塞属性。例如:
private BlockingQueue queue;
@Override
public void run() {
while(true) {
handle(queue.poll());
}
}
上面的代码是一个Runnable
- 您可以使用一个ExecutorService
开始运行的,或者用Thread
课程的qeueue外部设置了老式的方法,和被填充(再次外部)入局项目。
我认为BlockingQueue
和ThreadPoolExecutor
的组合可以满足您的需求。或者,如果您在Java EE应用服务器上部署,则可以使用JMS和消息驱动的Bean。
您可以在java.util.concurrent
库中找到所需的库 - 它是一个比Thread
更高级别的API。看看http://www.ibm.com/developerworks/java/library/j-jtp1126/index.html
既然你想要类似于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();
}
}