2017-03-06 39 views
1

固定スレッドプールを使用するサービスがあります。この重いタスクの10個以上のインスタンスが私のサーバーに多すぎるためです。私はそれをのようなものを使用ExecutorServiceにn個のスレッドとn個の対応するオブジェクトがあります

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); 

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

を今、私はまた、唯一のn MyHeavyClassWithCacheクラスの(10)のインスタンスを持っている必要があります。また、エグゼキュータで何とか再利用する必要があります(今のように作成する方がずっと早い)。 ExecutorServiceでこのようなことをどうやって管理できますか? 目標は、MyHeavyClassWithCacheクラスの10個のインスタンス(同時に同じインスタンスを持つスレッドは1つもありません)を使用して、同時に最大10個のスレッドを処理することです。

これは、これを達成するためのデザインパターン。

+1

あなたが探しているのはオブジェクトプールです。 commons-poolを使用してithttp://commons.apache.org/proper/commons-pool/ – seneque

+0

を実装することができます。これは私が必要とするものです。私はそれを実装し、これまでのところうまく動作します。答えとしてここにあなたのコメントを書いてください。どうもありがとう! –

答えて

0

目標はこれを行うにはいくつかの方法があります

MyHeavyClassWithCacheクラスの私の10個のインスタンスのいずれかを使用して同時に作業している最大10個のスレッドを達成することです。最も簡単な方法は、ThreadLocal<MyHeavyClassWithCache>を使用して、各プールスレッドが独自の「重い」クラスを取得することです。 RunnableインスタンスはThreadLocalを定義します。

代わりに、プールに10,HeavyRunnableのインスタンスをそれぞれ独自のローカルインスタンスMyHeavyClassWithCacheでサブミットし、別のBlockingQueueからデキューするようにすることもできます。これは私が以前使用したパターンです。

コードは次のようになります。

// 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() { ... }); 
... 

をそれは、これらの背景重いランナブルシャットダウンへの挑戦のビットですが、キューに10のnull Sを入れて、彼らがnullをデキューするときのスレッドのシャットダウンを持つことが一つの方法であります。

関連する問題