我有一个线程池,其中有固定数量的工作线程(比如4个)。我不停地把新的可运行程序取给执行器。所有这些可运行程序都有一个长时间的睡眠调用,等待另一个线程被它中断:
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个可运行程序提取到我的执行器时,所有工作线程都在休眠,而其他传入的可运行程序(其中很多,因为它们是连续传入的)都在排队,必须等待可用的线程。有没有办法,我可以使用睡眠线程来执行新的传入可运行程序,保持其他线程的睡眠?
不,正在休眠的线程正在休眠。你不能让它做别的事情。
你应该做的是添加一个按你想要的时间延迟的计划任务。这将释放当前线程,并允许它执行其他操作。
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);
}
}
IMHO,通过中断发送信号是非常不可靠的。不要编写依赖它的代码。
我不太确定语法,但你可以看看回调计时器。例如,您将run()方法分为两部分,preWork和postWork。完成preWork后,将对象添加到列表/映射/队列等中,并使用"comeToLife"值。然后,你的线程会查看这个队列,找到一个已经到达"comeToLife"时间的不同对象,并调用postWork。
如果你需要线程在中断后立即运行,你真的应该使用Lock或其他机制,因为InterruptException不会总是被调用。。。