如何设置两个彼此相邻的线程池?

时间:2018-11-27 23:01:12

标签: java multithreading pdf threadpool bmp

我有一个关于线程池的问题。

这是我的情况: 从后端服务的某个地方,我们会收到pdf文件列表。
首先需要将这些pdf页面一个一个地转换为.bmp文件。
转换后,需要打印这些bmp。

问题是转换和打印任务都需要一段时间才能完成,我想使此过程更快,因为否则可能要花一些时间才能有人看到打印机中有东西出来。

我考虑过的解决方案是创建2个ThreadPool:一个用于转换,另一个用于打印。

这些就是我的线程池:

ExecutorService convertPool = Executors.newFixedThreadPool(10);

ExecutorService printPool = Executors.newSingleThreadExecutor();

具有10个线程的convertPool,可将pdf页面转换为bmp。
完成此操作后,创建的bmp将发送到printPool。这是一个单线程,因为始终只能进行一次打印。

但现在我的问题是:
因此convertPool已完成了第一个pdf的工作,并将所有将来的任务发送到PrintPool进行打印。
但是当printPool繁忙时,我希望convertPool已经从第二个pdf开始。这样,当PrintPool完成后,就可以从第一个pdf打印bmp了,因为它已经创建,因此可以立即开始处理第二个pdf的bmp打印。

但是如何设置这种机制?有人可以帮我吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

  • 您可以使用同一执行程序来执行可运行的打印作业。
  • 在该可运行债券中,您可以参考由以下产品产生的期货清单 实际上正在处理PDF的可调用对象的执行。
  • 当然,该列表具有全球参考意义。
  • 现在您可以使用许可范围有限的信号量,例如(10),并且任何可调用的信号量
    结束执行,它可以释放可运行对象将要使用的许可证
    尝试事先获取并保持在阻止状态,因为没有可用状态。

    注意:每个可处理Callable的PDF处理都将在其开始执行时获得许可。

  • 您的可运行物品可以在获取任何许可证之前尝试获取许可证 返回Done()状态为true并可以释放 允许在迭代的末尾。

  • 所有任务都已完成执行,或者再次获得10个许可时,可以通过执行shutdownNow()终止执行程序,从而终止可运行程序。

希望有帮助!

答案 1 :(得分:0)

您处在正确的轨道上。您可以根据需要向转换器池提交任意数量的转换任务。它将尽快执行它们,并将那些还不能由线程服务的队列排队。每个转换任务完成后,它可以将自己提交给打印池,该打印池还将根据需要将任务排队。这是我的意思的基本骨架:

class Conversion implements Runnable {
    Consumer<Conversion> onCompletion;

    Conversion(Consumer<Conversion> onCompletion) {
        this.onCompletion = onCompletion;
    }

    @Override
    public void run() {
        // ... conversion code. You could Thread.sleep()
        // here to simulate the conversion work taking up
        // some time.

        // (now we're done converting)
        onCompletion.accept(this);
    }
}

class Print implements Runnable {
    Print(Conversion c) {
        // ...
    }

    // ...run() method, etc.
}

// Example of submitting a conversion task to the executor
convertPool.submit(new Conversion(c -> printPool.submit(new Print(c))));