0

我有一个模块,可以处理数千个要处理的事务。每笔交易都有多个阶段要经历。该模块以多线程模式执行。我们已经为它可以创建的线程数定义了限制(硬编码)(根据服务器利用率进行限制)。

现在我们遇到了一种情况,线程可能需要等待一段时间(可能超过 24 小时)。由于我们的线程数量有限,并且如果所有线程都等待超过 24 小时,这将完全阻塞应用程序。

我在这里需要的是,我应该如何重用等待等待 24 小时的线程。如果线程处于等待模式,我需要将该线程重用于另一个事务,当原始等待结束时,从它被搁置的位置重新启动原始事务。

我希望上面的描述能帮助你理解问题。

4

1 回答 1

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() 以允许它执行阻塞任务,但允许另一个线程在它阻塞时运行。

于 2013-01-31T10:14:42.563 回答