2009-04-28 13 views
4

私のアプリでは、カスタムThreadFactoryでスレッドプールを使用しています。私は(IDE、のIntelliJ IDEAから)現在のスレッドをダンプする場合は、スレッドプールに様々なランナブルを提出した後、私が手Java ThreadFactoryの問題

pool = Executors.newScheduledThreadPool(10, new TF()); 

class TF implements ThreadFactory { 
    AtomicInteger count = new AtomicInteger(1); 
    public synchronized Thread newThread(Runnable r) { 
     Thread t = new Thread(r) ; 
     t.setName("ThreadPool Thread[" + count.getAndIncrement() + "]"); 
     t.setUncaughtExceptionHandler(new UEHLogger()); 
     return t; 
    } 
} 

"ThreadPool Thread[1]" daemon prio=6 tid=0x0334e000 nid=0x1130 waiting on condition [0x0377f000..0x0377fc94] 
    java.lang.Thread.State: WAITING (parking) 
    at sun.misc.Unsafe.park(Native Method) 
    - parking to wait for <0x22fa7838> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1925) 
    at java.util.concurrent.DelayQueue.take(DelayQueue.java:160) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:583) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:576) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) 
    at java.lang.Thread.run(Thread.java:619) 

"ThreadPool Thread[1]" daemon prio=6 tid=0x0333e400 nid=0x128 waiting on condition [0x0372f000..0x0372fd14] 
    java.lang.Thread.State: TIMED_WAITING (parking) 
    at sun.misc.Unsafe.park(Native Method) 
    - parking to wait for <0x22edb9e0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1963) 
    at java.util.concurrent.DelayQueue.take(DelayQueue.java:164) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:583) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:576) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) 
    at java.lang.Thread.run(Thread.java:619) 

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

(スレッド2-9のsimliarスタックトレースと同様に)

スレッド番号1,2,3,4,5,6,7,8,9,10を取得する代わりに、スレッド番号1 、1,2,3,4,5,6,7,8,9

すべてが正常に動作しているように見えますが、明らかに戸惑っています。

+1

newThreadメソッドが同期されているので、特に注意が必要です。この場合、AtomicIntegerを使用する必要はありません。 –

+0

確かに。元のnewThreadメソッドは同期化されていませんでしたが、それが問題であると仮定しました。悲しいことではない。 – PaulJWilliams

+0

常に重複する最初のIDだけですか?または、他のIDが複数回も発生しますか? –

答えて

5

あなたは誤って2つのスレッドプール(または2つのThreadFactories)を作成していませんか?

これを確認するには、それぞれのスレッドがスレッドファクトリのIDを自身のidとともに出力するようにすることが考えられます。

+0

それはそれですね:-) –

1

Hmmでは、OpenJDKと次の(非常に単純化された)テストコードで問題を再現できません。以下はあなたのために何を与えるのですか?

class TF implements ThreadFactory { 

    class UEHLogger implements Thread.UncaughtExceptionHandler 
    { 
    public void uncaughtException(Thread t, Throwable e) { 
     System.out.println(t + " threw exception: " + e); 
    } 
    } 

    AtomicInteger count = new AtomicInteger(1); 
    public synchronized Thread newThread(Runnable r) { 
     Thread t = new Thread(r) ; 
     t.setName("ThreadPool Thread[" + count.getAndIncrement() + "]"); 
     t.setUncaughtExceptionHandler(new UEHLogger()); 
     return t; 
    } 

    public static void main(String[] a) 
    { 
    TF myTF = new TF(); 
    Thread[] threads = new Thread[10]; 
    for(int i = 0; i < threads.length; i++) 
     threads[i] = myTF.newThread(new Runnable(){public void run(){}}); 
    for(Thread t : threads) 
     System.out.println(t); 
    } 
}