如果你的系统中有长时间的延误,做的最好的是有更多的线程。如果你想限制同时运行的线程的数量,你可以使用许可,例如一个信号量,每当你阻塞操作时释放,并在阻塞结束时重新获得。这可确保您一次运行的线程数量有限,但可让您轻松地在多项任务之间切换。
public abstract class LimitedTask implements Runnable {
static final Semaphore PERMITS = new Semaphore(Runtime.getRuntime().availableProcessors());
@Override
public final void run() {
try {
PERMITS.acquire();
} catch (InterruptedException e) {
System.err.println("Task " + getClass() + " cancelled before it was started.");
return;
}
try {
runTask();
} finally {
PERMITS.release();
}
}
protected abstract void runTask();
protected void runBlockingTask(Runnable runnable) {
PERMITS.release();
try {
runnable.run();
} finally {
PERMITS.acquireUninterruptibly();
}
}
}
在这个例子中,你可以有尽可能多的这些,但只有有限的数字将在PERMIT区域内。这些任务还可以调用runBlockingTask()来允许它执行阻塞任务,但允许另一个线程在阻塞时运行。
你在使用'ExecutorService'还是一些等价的东西?每个“交易”应该是一项应该能够执行的任务。如果由于任何原因,交易无法完成,则应将其过帐到未决队列。您应该有一个独立的线程监视此待处理队列中是否有任何准备好执行的任务,并将其发布到执行程序服务以在下一个可用线程上执行。听起来像是对现有架构的轻微重新设计...... – Nim
当你说“线程将要等待几个小时”时,你的意思是“它会睡眠x小时,然后再试一次”或“它正在积极轮询某个事件从现在到几个小时之间的任何时间都可能发生“?对于后一种情况,我希望有一个序列化解决方案。 – SJuan76