我有一个具有固定工作线程数的线程池(比如4)。我不断地向执行者提取新的runnables。所有这些runnable都有一个长时间的睡眠调用,等待另一个线程被它打断:
Runnable runnable = new Runnable() {
@Override
public void run() {
//do preparation
doPreWork();
//wait for some other runnable to interrupt me
try {
Thread.sleep(40000);
}
catch(InterruptedException e) {
}
//finish work
doAfterWork();
}
}
所以问题是:当我将前4个runnables提取到我的执行器时,所有工作线程都处于休眠状态,其他传入的runnables(其中很多,因为它们不断传入)排队并且必须等待可用的线程。有什么办法,我可以使用休眠线程执行新的传入runnables,让其他人保持睡眠状态?
答案 0 :(得分:2)
不,睡觉的线程在睡觉。你不能让它做其他事情。
您应该做的是添加一个延迟了您想要的时间的计划任务。这将释放当前线程并允许它执行其他操作。
ScheduledExecutorService ses = ...
ses.submit(new Runnable() {
@Override
public void run() {
//do preparation
doPreWork();
ses.schedule(new Runnable() {
@Override
public void run() {
//finish work
doAfterWork();
}
}, 40000);
}
}
恕我直言,通过中断发送信号是非常不可靠的。不要编写依赖它的代码。
答案 1 :(得分:0)
我对语法不太确定,但你可以查看一个回调计时器。例如,您将run()方法拆分为preWork和postWork两部分。完成预工作后,将对象添加到列表/地图/队列等,并使用“生命周期”和“生命周期”。值。然后你的线程会查看这个队列,找到一个不同的对象,其中包含了来自生活的对象。时间已经到了,并打电话给postWork。
如果你的线程在被中断时需要运行,你应该使用Lock或其他一些机制,因为InterruptException不会总是被调用...