2009-08-11 63 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共享,因此对于您的应用程序,它可以从任何数字开始。