2009-08-11 62 views
4

我正在進行互斥任務,但是當我開始時,我發現我的應用程序的線程ID從9開始。當我再次編譯和執行它時,它不會改變。有沒有我缺少的問題,或者Java Thread ID是否可以以任意數字開始? This question是相關的。Java線程ID是否應始終從0開始?


對於那些有興趣,這裏是從赫利希&沙維特的「多處理器編程的藝術」一類的編號線程:

public class ThreadID { 
    private static volatile int nextID = 0; 
    private static class ThreadLocalID extends ThreadLocal<Integer> { 
     protected synchronized Integer initialValue() { 
      return nextID++; 
     } 
    } 

    private static ThreadLocalID threadID = new ThreadLocalID(); 
    public static int get() { 
     return threadID.get(); 
    } 
    public static void set(int index) { 
     threadID.set(index); 
    } 
} 

然後,您可以撥打

ThreadID.get(); 

這將自動遞增數字並始終從1開始。

回答

7

F從Thread#getId()文檔:

返回此線程的標識符。 線程ID是一個正數 當該線程被創建時產生的 數字。線程ID是唯一的,並且 在其生命週期內保持不變。 線程終止時,可能會重用此線程ID。

沒有證據表明它保證會從0開始。我猜想,在內部,Java使得您創建的第一個前幾個線程對象,因此,線程ID 0 – 8已經被佔用。然而,文檔中沒有任何內容保證這個數字將以任何順序連續(儘管這是目前實現的),所以你不應該依賴這個數字。

0

我不知道是否有一個規範定義此,或如何可靠和一致的這個編號將是的,但你在你的代碼中創建線程是不是在系統中第一個運行的線程,一些線程在您的代碼作爲JVM的一部分運行之前啓動。 以下是jstack說是對我的JVM上運行,當我運行的代碼(在那裏,所以我可以衡量睡眠):

"Attach Listener" daemon prio=10 tid=0x000000004038c400 nid=0x3adf runnable [0x0000000000000000..0x0000000000000000] 
    java.lang.Thread.State: RUNNABLE 

"Low Memory Detector" daemon prio=10 tid=0x00007f7dc4002400 nid=0x3ac5 runnable [0x0000000000000000..0x0000000000000000] 
    java.lang.Thread.State: RUNNABLE 

"CompilerThread1" daemon prio=10 tid=0x0000000040386400 nid=0x3ac4 waiting on condition [0x0000000000000000..0x0000000000000000] 
    java.lang.Thread.State: RUNNABLE 

"CompilerThread0" daemon prio=10 tid=0x0000000040384000 nid=0x3ac3 waiting on condition [0x0000000000000000..0x0000000000000000] 
    java.lang.Thread.State: RUNNABLE 

"Signal Dispatcher" daemon prio=10 tid=0x0000000040382000 nid=0x3ac2 runnable [0x0000000000000000..0x0000000040c43710] 
    java.lang.Thread.State: RUNNABLE 

"Finalizer" daemon prio=10 tid=0x0000000040363000 nid=0x3ac1 in Object.wait() [0x0000000042186000..0x0000000042186a00] 
    java.lang.Thread.State: WAITING (on object monitor) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x00007f7dfaaa1210> (a java.lang.ref.ReferenceQueue$Lock) 
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116) 
    - locked <0x00007f7dfaaa1210> (a java.lang.ref.ReferenceQueue$Lock) 
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132) 
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) 

"Reference Handler" daemon prio=10 tid=0x000000004035bc00 nid=0x3ac0 in Object.wait() [0x0000000042085000..0x0000000042085d80] 
    java.lang.Thread.State: WAITING (on object monitor) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x00007f7dfaaa1078> (a java.lang.ref.Reference$Lock) 
    at java.lang.Object.wait(Object.java:485) 
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116) 
    - locked <0x00007f7dfaaa1078> (a java.lang.ref.Reference$Lock) 

"main" prio=10 tid=0x00000000402f5800 nid=0x3abc waiting on condition [0x0000000041015000..0x0000000041015ec0] 
    java.lang.Thread.State: TIMED_WAITING (sleeping) 
    at java.lang.Thread.sleep(Native Method) 
    at Simulation.main(Simulation.java:16) 

"VM Thread" prio=10 tid=0x0000000040356400 nid=0x3abf runnable 

"GC task thread#0 (ParallelGC)" prio=10 tid=0x0000000040300400 nid=0x3abd runnable 

"GC task thread#1 (ParallelGC)" prio=10 tid=0x0000000040301c00 nid=0x3abe runnable 

"VM Periodic Task Thread" prio=10 tid=0x00007f7dc4004c00 nid=0x3ac6 waiting on condition 
2

是。但線程ID由整個JVM共享,因此對於您的應用程序,它可以從任何數字開始。