2016-10-15 2 views
4

私は独自のスレッドプールと、呼び出し可能なインターフェイスの並列を実行できる将来のオブジェクトを作成しています。 Executorは、シャットダウンメソッドを提供して、すべてのワーカースレッドの実行を停止します。以下のようなスレッドプールを作成している場合は、すべてのスレッドの実行が終了した後に停止する方法を実装する必要がありますか?executorServiceのシャットダウンメソッドをオーバーライドする方法

マイカスタム・スレッド・プールは、私は、スレッドのリストを維持するための方法を考えると、彼らはアイドル状態にあるかどうかをチェックcouldntのthis

class MyThreadPool implements java.util.concurrent.Executor 
{ 
    private final java.util.concurrent.BlockingQueue<Callable> queue; 

    public MyThreadPool(int numThreads) { 
     queue = new java.util.concurrent.LinkedBlockingQueue<>(); 
     for (int i=0 ; i<numThreads ; i++) { 
      new Thread(new Runnable(){ 
       @Override 
       public void run() { 
        while(true) { 
         queue.take().call(); 
        } 
       } 
      }).start(); 
     } 
    } 

    @Override 
    public <T> Future<T> submit(Callable<T> callable) { 
    FutureTask<T> future = new FutureTask(callable); 
    queue.put(future); 
    return future; 
    } 

    public void shutdown(){ } 
} 

のように見えますか?

答えて

1

作成しているスレッドの参照は間違いなく保持する必要があります。たとえば、フィールドthreadsList<Thread>に設定し、コンストラクタ内からこのリストにスレッドを追加します。

public void shutdown() { 
    for (Thread t : threads) { 
     try { 
      t.join(); 
     } catch (InterruptedException e) { /* NOP */ } 
    } 
} 

は、適切な条件で while (true)を置き換えることを忘れないでください(あなたが shutdown()に切り替えている)と BlockingQueue#poll(long, TimeUnit)ではなく take()を使用することを検討してください:

その後は、Thread#join()の助けを借りてshutdown()を実装することができます。

EDIT:何かのように:

public class MyThreadPool implements Executor { 

    private List<Thread> threads = new ArrayList<>(); 
    private BlockingDeque<Callable> tasks = new LinkedBlockingDeque<>(); 
    private volatile boolean running = true; 

    public MyThreadPool(int numberOfThreads) { 
     for (int i = 0; i < numberOfThreads; i++) { 
      Thread t = new Thread(() -> { 
       while (running) { 
        try { 
         Callable c = tasks.poll(5L, TimeUnit.SECONDS); 
         if (c != null) { 
          c.call(); 
         } 
        } catch (Exception e) { /* NOP */ } 
       } 
      }); 
      t.start(); 
      threads.add(t); 
     } 
    } 

    public void shutdown() { 
     running = false; 
     for (Thread t : threads) { 
      try { 
       t.join(); 
      } catch (InterruptedException e) { /* NOP */ } 
     } 
    } 

    // ... 

} 
+0

私はこれをやってみましたが、まだスレッドが、私はそれ故にキューから呼び出し可能取るための条件を待っているスレッドがあるbecuause理由があるbeileve – krs8888

+0

を実行しているように見えます終了しません。私が間違っている場合は私を修正してください – krs8888

+0

はい、これは動作しますが、私のキューをポーリングしたくありません。私はしかし、私のシャットダウンの方法でpoison pillのアプローチを使用しました。私がしたことは、シャットダウンメソッドのキューにpoisonオブジェクトが追加されたことです。キューから取り出したら、それが毒であるかどうかを確認します。もしそうなら、私はループから脱出する – krs8888

関連する問題