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

Java 具有n个线程和n个相应对象的ExecutorService,java,multithreading,executorservice,Java,Multithreading,Executorservice,我有一个使用固定线程池的服务,因为这个繁重任务的10个以上实例对我的服务器来说太多了 ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); 我用它来表示: Runnable command = new Runnable() { @Override public void run() { MyHeavyClassWithCache myHeavyClas

我有一个使用固定线程池的服务,因为这个繁重任务的10个以上实例对我的服务器来说太多了

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);
我用它来表示:

Runnable command = new Runnable() {
        @Override
        public void run() {
            MyHeavyClassWithCache myHeavyClassWithCache=new MyHeavyClassWithCache();
        }
    };
    Future<ScreenImage> feature = executor.submit(command,myHeavyClassWithCacheResult);
// 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() { ... });
...
Runnable命令=新建Runnable(){
@凌驾
公开募捐{
MyHeavyClassWithCache MyHeavyClassWithCache=新建MyHeavyClassWithCache();
}
};
Future feature=executor.submit(命令,myHeavyClassWithCacheResult);
现在我只需要有n(10)个MyHeavCyclassWithCache类的实例。而且还需要在executor中以某种方式重用它(比像我现在这样创建它要快得多)。 我如何使用ExecutorService管理这种事情。 目标是通过使用MyHeavCyclassWithCache类的10个实例中的一个来实现最多10个线程同时工作(决不能同时使用相同实例的两个线程!)

我希望这足够普遍,可以存在一些java设计模式来实现这一点

目标是通过使用MyHeavCyclassWithCache类的10个实例之一,实现最多10个线程同时工作

有几种方法可以做到这一点。最简单的方法可能是使用
ThreadLocal
,这样每个池线程都有自己的“重”类。您的
Runnable
实例将定义
ThreadLocal

另一种选择是将10个
HeavyRunnable
实例提交到您的池中,每个实例都有自己的
MyHeavyClassWithCache
本地实例,并让这些实例从不同的
BlockingQueue
中退出队列。这是我以前使用过的模式

代码可能类似于:

Runnable command = new Runnable() {
        @Override
        public void run() {
            MyHeavyClassWithCache myHeavyClassWithCache=new MyHeavyClassWithCache();
        }
    };
    Future<ScreenImage> feature = executor.submit(command,myHeavyClassWithCacheResult);
// 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() { ... });
...
//从阻塞队列中退出队列并保留重实例的runnable
私有静态类HeavyRunnable实现可运行{
private final MyHeavyClassWithCache heavy=新建MyHeavyClassWithCache();
私有最终阻塞队列runnableQueue;
public HeavyRunnable(BlockingQueue runnableQueue){
this.runnableQueue=runnableQueue;
}
公开募捐{
而(!Thread.currentThread.isInterrupted()){
Runnable=runnableQueue.take();
//如果我们看到空值,则停止运行
if(runnable==null){
打破
}
runnable.run();
}
}
}
...
final ExecutorService newFixedThreadPool=Executors.newFixedThreadPool(10);
final BlockingQueue runnableQueue=新建LinkedBlockingQueue();
添加(新的HeavyRunnable(runnableQueue));
...
添加(新的Runnable(){…});
...
关闭这些后台可运行程序有点困难,但将10个
null
s放入队列中,并在线程退出队列时关闭
null
是一种方法

目标是通过使用MyHeavCyclassWithCache类的10个实例之一,实现最多10个线程同时工作

有几种方法可以做到这一点。最简单的方法可能是使用
ThreadLocal
,这样每个池线程都有自己的“重”类。您的
Runnable
实例将定义
ThreadLocal

另一种选择是将10个
HeavyRunnable
实例提交到您的池中,每个实例都有自己的
MyHeavyClassWithCache
本地实例,并让这些实例从不同的
BlockingQueue
中退出队列。这是我以前使用过的模式

代码可能类似于:

Runnable command = new Runnable() {
        @Override
        public void run() {
            MyHeavyClassWithCache myHeavyClassWithCache=new MyHeavyClassWithCache();
        }
    };
    Future<ScreenImage> feature = executor.submit(command,myHeavyClassWithCacheResult);
// 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() { ... });
...
//从阻塞队列中退出队列并保留重实例的runnable
私有静态类HeavyRunnable实现可运行{
private final MyHeavyClassWithCache heavy=新建MyHeavyClassWithCache();
私有最终阻塞队列runnableQueue;
public HeavyRunnable(BlockingQueue runnableQueue){
this.runnableQueue=runnableQueue;
}
公开募捐{
而(!Thread.currentThread.isInterrupted()){
Runnable=runnableQueue.take();
//如果我们看到空值,则停止运行
if(runnable==null){
打破
}
runnable.run();
}
}
}
...
final ExecutorService newFixedThreadPool=Executors.newFixedThreadPool(10);
final BlockingQueue runnableQueue=新建LinkedBlockingQueue();
添加(新的HeavyRunnable(runnableQueue));
...
添加(新的Runnable(){…});
...

关闭这些后台可运行程序有点困难,但将10个
null
s放入队列中,并在线程退出队列时关闭
null
是一种方法。

您要寻找的是一个对象池。您可以使用commons池来实现ithttp://commons.apache.org/proper/commons-pool/Yes 这就是我需要的。我实现了它,到目前为止效果很好。在这里写下你的评论作为答案。谢谢!您正在寻找的是一个对象池。您可以使用commons池来实现ithttp://commons.apache.org/proper/commons-pool/Yes 这就是我需要的。我实现了它,到目前为止效果很好。在这里写下你的评论作为答案。谢谢!