ThreadLocal <T>Документация в JDK - PullRequest
0 голосов
/ 19 октября 2011

В документации JDK 1.6 приведен пример использования LocalThread<T>.Я копирую и вставляю его сюда:

Например, класс ниже генерирует уникальные идентификаторы, локальные для каждого потока.Идентификатор потока назначается при первом вызове UniqueThreadIdGenerator.getCurrentThreadId() и остается неизменным при последующих вызовах.

 import java.util.concurrent.atomic.AtomicInteger; 

 public class UniqueThreadIdGenerator {    
     private static final AtomicInteger uniqueId = new AtomicInteger(0);    
     private static final ThreadLocal <Integer> uniqueNum = 
         new ThreadLocal <Integer> () {
             @Override 
             protected Integer initialValue() {
                 return uniqueId.getAndIncrement();
         }
     };

     public static int getCurrentThreadId() {
         return uniqueId.get();
     }
 } // UniqueThreadIdGenerator

Моя проблема:

когда несколько потоков вызывают UniqueThreadIdGenerator.getCurrentThreadId(), возвращается только 0потому что нет инициализации.Разве это не должно быть так:

public static int getCurrentThreadId() {
    return uniqueNum.get();
}

Теперь после первого вызова происходит инициализация переменной.

1 Ответ

5 голосов
/ 19 октября 2011

Да, это должно быть uniqueNum.get(). JDK 7 документов понимают это правильно и используют более подходящие имена:

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadId {
    // Atomic integer containing the next thread ID to be assigned
    private static final AtomicInteger nextId = new AtomicInteger(0);

    // Thread local variable containing each thread's ID
    private static final ThreadLocal<Integer> threadId =
        new ThreadLocal<Integer>() {
            @Override protected Integer initialValue() {
                return nextId.getAndIncrement();
        }
    };

    // Returns the current thread's unique ID, assigning it if necessary
    public static int get() {
        return threadId.get();
    }
}

Хотя на самом деле это не инициализация - это просто вопрос использованияне тот член целиком.Даже если бы в большом количестве кода было использовано uniqueNum в исходном коде, getCurrentThreadId() всегда возвращало бы "следующий назначаемый идентификатор" вместо "идентификатора, назначенного для текущего потока".

...