2016-06-22 10 views
1

いくつかのデータをブロッキングキューに入れ、スレッドタスクを固定スレッドプールに基づいてJava実行プログラムサービスに送信するコードを実行しました。エグゼキュータをシャットダウンしようとするとシャットダウンしませんが、どうしたらいいですか?Javaスレッド実行プログラムはシャットダウンしませんか?

import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class ThreadExecutir { 
    public static ArrayBlockingQueue<String> files; 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     shutdownExec(); 
    } 

    private static void shutdownExec() { 
     int size = 10; 
     files = new ArrayBlockingQueue<String>(100); 
     for (int i = 0; i < 5; i++) { 
      files.add("Java " + i); 
     } 

     ThreadExecutir outer = new ThreadExecutir(); 
     ExecutorService executor = Executors.newFixedThreadPool(size); 
     for (int i = 0; i < 3 * size; i++) { 
      executor.submit(outer.new myThread()); 
     } 
     System.out.println(executor.isShutdown()); 
     executor.shutdown(); 

     try { 
      executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 
      System.out.println("Awaiting for threads to complete!"); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     if (files.isEmpty()) 
      executor.shutdownNow(); 
     System.out.println(executor.isShutdown()); 

    } 

    class myThread extends Thread { 
     public void run() { 

      String threadName = Thread.currentThread().getName(); 
      System.out.println("Thread " + threadName + "started running! "); 
      try { 
       String uploadThis = files.take(); 
       System.out.println("I'm working " + threadName + " " 
         + uploadThis); 
       // this.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } finally { 
       System.out.println("Thread " + threadName 
         + " finished running! "); 
      } 
     } 
    } 
} 

答えて

4

myThreadインスタンスは、filesfiles.take()上の残りのブロックをすべての要素を消費した後。

shutdown状態のjavadocの

は以前に提出したタスクが を実行される通常のシャットダウンを開始しますが、新しいタスクは受け入れられません。すでにシャットダウンされている場合は、呼び出しに の追加効果はありません。

shutdownに電話する前に、30件のタスク(10件が実行中)をすべて送信しました。したがって、彼らはすべてExecutorServiceが終了するとみなされる前に実行を終了する必要があります。しかし、現時点では、take()でブロッキングを止めることができないため、ほとんどが実行を終了できません。

ArrayBlockingQueueにさらにアイテムを送信するか、ExecutorServiceのスレッドを中断する必要があります。 shutdownNowは、これらのスレッドを中断するために使用できます。

ブロッキング呼び出しの前に割り込みが到着する可能性があるため、割り込みをスレッドを停止するのに十分でない可能性があることに注意してください。 sophisticated solution, like a poison pillが必要です。


あなたがThread

class myThread extends Thread { 

をサブクラス化してきましたが、あなただけのRunnableThread実装Runnable)としてmyThreadを使用しています。これはかなり無意味です。ただ実装するRunnable

class myThread implements Runnable { 
+0

私はキューに毒薬を追加しましたが、スレッドはまだ自分では死ぬことはありません!何か案が? –

1

あなたはキューに5つの文字列と30のタスクを提出しました。最初の5つのタスクはfilesから5つの文字列をすべて消費し、次の1つはブロックされて、poll()文字列(空のキューからnotEmpty.await()が呼び出されます)を試行します。

スレッドは、中断されるまで待機します。エグゼキュータはスレッドが終了するまで待機します。

ので、コードがexecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)に引っかかって、決してあなたの代わりにfiles.take()files.poll()を使用する必要がありますようにif (files.isEmpty()) executor.shutdownNow();

が見える達するだろう - それは空のキューreturn (count == 0) ? null : dequeue();にロックされません。

関連する問題