我环顾四周,但还没有找到答案,所以我想确认一下。Java线程池/执行程序服务和wait()s - 线程和任务队列发生了什么?
说我有一个固定大小的线程池 - ExecutorService pool = Executors.newFixedThreadPool(5);
而且我有一些代码:
pool.execute(new Runnable(){
try{
Object waitForMe = doSomethingAndGetObjectToWaitFor();
waitForMe.wait();
doSomethingElse();
}catch(Exception e){ throw new RunTimeException(e) }
});
让我们假设上面的代码被称为几百倍。池中只有5个线程(所以上面的语句中只有5个应该在一个点上)。另外假设wait()
位于一个对象上,该对象正在对第三方进行一些I/O调用,并在操作完成时等待回调,因此自然需要一段时间才能完成。
现在我的问题是,当其中一个任务达到wait()
时的行为是什么,任务是否进入休眠状态,然后线程池中的线程将另一个任务从队列中取出并开始运行?
如果正在等待的任务进入睡眠状态,当它获得notify()
并且醒来时会发生什么?线程是否回到线程池的队列中(在前面或后面),并等待5个线程中的一个线程能够继续执行它(即调用doSomethingelse()
)?或者执行它的线程也进入休眠状态,即5个执行程序线程中的一个线程等待任务(这是我所假设的)?或者执行程序线程接受另一个任务,并在第一个任务从wait()返回时被简单地中断?
感谢您的好评!通过回调选项,设置超时的最佳方式是什么(比如说,如果没有任何错误发生,则希望等待回调x秒)。我能想到的唯一方法是记下当前系统毫秒数并将其保存在一个列表中,并让另一个线程监视超出当前时间并触发错误的呼叫列表。我需要找到一本关于并发,回调等的好书。再次感谢! – NightWolf 2012-03-01 11:02:14
@NightWolf:关于超时查看我更新的答案。当谈到一本好书时,[Java并发实践](http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601)是必须的。 – 2012-03-01 11:06:05
感谢您的更新和图书链接,好主意。可悲的是我对第三方没有任何控制权。 – NightWolf 2012-03-01 11:12:04