简体   繁体   English

具有n个线程和n个相应对象的ExecutorService

[英]ExecutorService with n threads and n corresponding objects

I have service that use fixed thread pool because more then 10 instances of this heavy task will be too much for my server. 我有使用固定线程池的服务,因为这个繁重任务的10多个实例对我的服务器来说太多了。

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);

I use it something like: 我用它像:

Runnable command = new Runnable() {
        @Override
        public void run() {
            MyHeavyClassWithCache myHeavyClassWithCache=new MyHeavyClassWithCache();
        }
    };
    Future<ScreenImage> feature = executor.submit(command,myHeavyClassWithCacheResult);

Now I need to have also only n (10) instances of MyHeavyClassWithCache class. 现在我还需要只有n(10)个MyHeavyClassWithCache类的实例。 And also need to reuse it somehow in executor (much faster then to create it like I do now). 并且还需要在执行程序中以某种方式重用它(比我现在更快地创建它)。 How can I manage this kind of thing with ExecutorService. 如何使用ExecutorService管理此类事情。 Goal is to achieve that max 10 threads working at the same time by using one of my 10 instances of MyHeavyClassWithCache class (never two threads with same instances at same time!) 目标是通过使用我的10个MyHeavyClassWithCache类实例中的一个来实现最多10个线程同时工作(从来没有两个线程同时具有相同的实例!)

I hope this is common enough to exists some java design pattern to achieve this. 我希望这足以存在一些java设计模式来实现这一点。

Goal is to achieve that max 10 threads working at the same time by using one of my 10 instances of MyHeavyClassWithCache class 目标是通过使用MyHeavyClassWithCache类的10个实例中的一个实现最多10个线程同时工作

There are a couple of ways to do this. 有几种方法可以做到这一点。 The easiest way may be to use a ThreadLocal<MyHeavyClassWithCache> so that each of the pool threads gets their own "heavy" class. 最简单的方法可能是使用ThreadLocal<MyHeavyClassWithCache>以便每个池线程获得自己的“重”类。 Your Runnable instances would define the ThreadLocal . 您的Runnable实例将定义ThreadLocal

The alternative would be to submit 10 HeavyRunnable instances to your pool, each with their own local instance of MyHeavyClassWithCache and have those dequeue from a different BlockingQueue . 另一种方法是向池中提交10个HeavyRunnable实例,每个实例都有自己的MyHeavyClassWithCache本地实例,并从不同的BlockingQueue This is a pattern that I've used before. 这是我以前用过的模式。

The code might look something like: 代码可能类似于:

// runnable that dequeues from a blocking queue and keeps a heavy instance
private static class HeavyRunnable implements Runnable {
    private final MyHeavyClassWithCache heavy = new MyHeavyClassWithCache();
    private final BlockingQueue<Runnable> runnableQueue;
    public HeavyRunnable(BlockingQueue<Runnable> runnableQueue) {
        this.runnableQueue = runnableQueue;
    }
    public void run() {
        while (!Thread.currentThread.isInterrupted()) {
             Runnable runnable = runnableQueue.take();
             // if we see a null then stop running
             if (runnable == null) {
                 break;
             }
             runnable.run();
        }
    }
}

...
final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);
final BlockingQueue<Runnable> runnableQueue = new LinkedBlockingQueue<>();
newFixedThreadPool.add(new HeavyRunnable(runnableQueue));
...
runnableQueue.add(new Runnable() { ... });
...

It's a bit of a challenge to shutdown these background heavy runnables but putting 10 null s in the queue and having the threads shutdown when they dequeue null is one way. 关闭这些后台繁重的runnables是一个挑战,但是在队列中放入10个null并且当它们出列null时线程关闭是一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM