2009-04-28 17 views
4

In meiner App verwende ich einen Threadpool mit einer benutzerdefinierten ThreadFactory.Problem mit Java ThreadFactory

Mein Code sieht so aus:

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; 
    } 
} 

jedoch nach verschiedenen Runnables an den Threadpool einreichen, wenn ich die aktuellen Themen (von der IDE, IntelliJ IDEA) Dump, die ich erhalten:

"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) 

(Sowie ähnliche Stack Traces für die Threads 2-9 inklusive)

Also im Grunde anstelle der Gewinde Nummer 1,2,3,4,5,6,7,8,9,10 bekomme ich Threads mit der Nummer 1 , 1,2,3,4,5,6,7,8,9

Alles scheint zu funktionieren, OK, aber es ist offensichtlich beunruhigend.

+1

Es ist besonders beunruhigend, da die newThread-Methode synchronisiert ist. Sie sollten in diesem Fall nicht einmal einen AtomicInteger verwenden müssen ... –

+0

In der Tat. Die ursprüngliche newThread-Methode wurde nicht synchronisiert, und ich nahm an, dass das das Problem war. Leider nicht. – PaulJWilliams

+0

Wird nur die erste ID immer dupliziert? Oder tauchen andere IDs auch mehrfach auf? –

Antwort

5

Sie haben nicht unbeabsichtigt zwei Threadpools (oder zwei ThreadFactories) erstellt, oder?

Es kann eine Idee sein, dies zu bestätigen, indem jeder Thread die ID seiner Thread-Factory neben seiner eigenen ID ausgeben soll.

+0

Sieht aus als wäre es das :-) –

1

Hmm, kann das Problem mit OpenJDK und dem folgenden (stark vereinfachten) Testcode nicht reproduzieren. Was gibt das Folgende für dich?

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); 
    } 
}