Должны ли идентификаторы потоков Java всегда начинаться с 0? - PullRequest
4 голосов
/ 11 августа 2009

Я работаю над назначением взаимного исключения, но при запуске я заметил, что идентификатор потока моего приложения начинается с 9. Он не меняется, когда я компилирую и выполняю его снова. Есть какая-то проблема, которую я пропускаю, или идентификаторы потоков Java могут начинаться с произвольного числа? Этот вопрос связан.


Для тех, кто заинтересован, вот класс из «Искусства многопроцессорного программирования» Херлихи и Шавита для нумерации потоков:

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.

Ответы [ 4 ]

7 голосов
/ 11 августа 2009

Из документации Thread#getId():

Возвращает идентификатор этой темы. Идентификатор потока является положительным длинным число, созданное, когда эта тема была создано. Идентификатор потока уникален и остается неизменным в течение своей жизни. Когда поток завершается, это ID потока может быть использован повторно.

Ничто не указывает на то, что гарантированно начнется с 0. Я предполагаю, что внутренне Java создает несколько объектов Thread перед созданным вами первым, и, таким образом, идентификаторы потоков 0 - 8 уже заняты. Тем не менее, ничто в документации не гарантирует, что это число будет каким-либо образом последовательным (хотя именно так оно и реализовано), поэтому вы не должны зависеть от этого.

2 голосов
/ 11 августа 2009

Да. Но идентификатор потока является общим для всей JVM, поэтому для вашего приложения он может начинаться с любого числа.

0 голосов
/ 11 августа 2009

Идентификатор потока - это положительное длинное число, созданное при создании этого потока. Идентификатор потока является уникальным и остается неизменным в течение всего срока службы. Когда поток завершается, этот идентификатор потока может использоваться повторно.

ссылка: http://java.sun.com/javase/6/docs/api/java/lang/Thread.html

Не нужно начинать с 0 или любого другого числа.

0 голосов
/ 11 августа 2009

Я не знаю, есть ли спецификация, которая определяет это, или насколько надежной или непротиворечивой будет эта нумерация, но потоки, которые вы создаете в своем коде, не являются первыми запущенными потоками в системе, число потоков Запустите, прежде чем ваш код будет работать как часть 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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...