5

私は、ArrayBlockingQueueからメッセージを消費する実行者を持っています。スレッドがjava.util.concurrent.ThreadPoolExecutor.getTaskでパークされる理由は何ですか?

new ThreadPoolExecutor(1, 1, 0L, 
       TimeUnit.MILLISECONDS, 
       new LinkedBlockingQueue<>(1), 
       r -> { 
        return new Thread(r, "Request-Queue-Drainer"); 
       }); 

Request-Queue-DrainerスレッドはWAITING状態です(タスクはこのスレッドに送信されていますが)。以下はスレッドダンプです。

Name: Request-Queue-Drainer 
State: WAITING on java.u[email protected]5b4757a2 
Total blocked: 0 Total waited: 8 

Stack trace: 
sun.misc.Unsafe.park(Native Method) 
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) 
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
java.lang.Thread.run(Thread.java:745) 

スレッドが待機状態になる理由は何ですか?

+0

「キューからメッセージを排除する責任がありますか?」とはどういう意味ですか?ここでは非常に普通の 'ThreadPoolExecutor'を構築しています。明示的な 'ThreadFactory'を渡しますが、' ThreadFactory'がデフォルトのスレッドファクトリと異なるのは、新しいスレッドにそれぞれ特別な名前を与えることだけです。 –

答えて

4

キューが空であるためスレッドが待機しています。プールスレッドは、キューからタスクを取り出して実行し、キューが空の場合は待機します。


編集:労働者の数がcorePoolSizeより大きくなっている場合ThreadPoolExecutorは、プールスレッドが死ぬことを原因とポイズンピルメッセージで送信することができます何か他のものは、キューが空のとき発生する可能性があることがありますkeepAlive時間単位以上。あなたの場合は、maximumPoolSizecorePoolSizeを同じ番号(1)に設定しているため、それは起こりません。


私はあなたのThreadPoolExecutorはあなたが唯一の保留中のタスクを持つことができることを除いてExecutors.newFixedThreadPool(1)によって返される1とは異なるいずれかを動作するように期待していない、それはプールが特別な名前をスレッド与えます。

関連する問題