我有一个模块可以处理数以千计的事务。每笔交易都有多个阶段要经历。该模块以多线程模式执行。 我们已经为它可以创建的线程数定义了限制(硬编码)(根据服务器利用率限制)。
现在我们遇到了一种情况,线程可能需要等待一段时间(可能超过24小时)。由于我们的线程数量有限,并且所有线程都在等待超过24小时,这完全阻止了应用程序。
我需要的是,我应该如何重用等待24小时的线程。 如果线程进入等待模式,我需要重新使用该线程进行anather事务处理,当原始等待结束时,重新启动原始事务,并将其置于保持状态。
我希望以上描述可以帮助你理解问题。
答案 0 :(得分:0)
如果你的系统有很长的延迟,最好的办法是拥有更多的线程。如果要限制并发运行的线程数,可以使用许可证,例如每当你有阻塞操作时释放的信号量,当阻塞完成时重新获取。这可确保您一次运行有限数量的线程,但允许您轻松地在多个任务之间切换。
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()以允许它执行阻塞任务,但允许另一个线程在阻塞时运行。