强制执行ThreadPoolExecutor执行的作业的顺序

时间:2015-11-12 23:48:27

标签: java multithreading synchronization

我有一堆要求严格的操作可以并行运行,但必须以某种顺序完成。完成后我的意思是将结果写入文件。当然,我可以在所有工作完成后重新排序结果,但我想避免这种情况(特别是因为结果可能太大而无法保存在内存中)。

我使用修改后的ThreadPoolExecutor并行运行作业,以确保一次只运行有限数量的作业以减少内存消耗。

我的想法是每个作业都会引用前一个作业,在写入结果之前,它将等到上一个作业完成(如果需要)。这似乎是一个简单的同步问题,但由于我没有这种东西的经验,我希望听到一个意见,如果它实际上按预期工作。还有关于内存管理。作业完成后,垃圾收集器应该能够从内存中删除它。

abstract public class WaitingJob extends Job {

    /** Job to wait for before we finish this job */
    protected WaitingJob previousJob;

    /** Job status */
    protected boolean finished = false;

    public WaitingJob(WaitingJob previousJob) {
        this.previousJob = previousJob;
    }

    @Override
    public void run() {
        // Perform the actual job (which might decide to wait for the previous one)
        runWithWaiting();

        // Wake up any job that's waiting for us.
        synchronized (this) {
            finished = true;
            notifyAll();
        }

        // Release memory (manually, to break the chain).
        previousJob = null;
    }

    /** If the previous job is not finished yet, let's wait for it. */
    protected void waitForPreviousJob() throws InterruptedException {
        if (previousJob != null) {
            synchronized (previousJob) {
                while (!previousJob.finished) {
                    previousJob.wait();
                }
            }
        }
    }

    /** Perform the job with the possibility to wait on the previous one. */
    protected abstract void runWithWaiting();
}

示例工作:

class SampleJob extends WaitingJob {
    @Override
    protected void runWithWaiting() {
        try {
            Thread.sleep(1000);  // Do heavy work
            waitForPreviousJob();
            // Write down work
        } catch (InterruptedException e) {
        }
    }
}

我对此进行了几次测试,似乎表现得应该如此,但我不确定是否有任何危险的时刻。

此外,是否有更好的解决方案?

1 个答案:

答案 0 :(得分:1)

在我看来,这应该有效并且是一个合理的解决方案。唯一可能的问题是,根据代码的其余部分,所有线程可能会占用正在等待尚未分配线程的作业的作业,从而导致死锁(例如,在池中有四个线程,作业2-5完成并使其线程处于等待状态,而作业1无法获得线程,因为它们全部被占用)。但是,这可能不适用于您的情况。