简体   繁体   中英

ThreadLocal<T> Documentation in JDK

JDK 1.6 documentation shows an example about how to use LocalThread<T> . I copy and paste it here:

For example, the class below generates unique identifiers local to each thread. A thread's id is assigned the first time it invokes UniqueThreadIdGenerator.getCurrentThreadId() and remains unchanged on subsequent calls.

 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

My problem is:

when multiple threads call UniqueThreadIdGenerator.getCurrentThreadId() it only returns 0 because there is no initialization. Shouldn't it be like this:

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

Now after the first call, it goes and initialize the variable.

Yes, it should be uniqueNum.get() . The JDK 7 docs get it right, and use better names:

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

It's not really a matter of initialization though - it's simply a matter of using the wrong member entirely. Even if lots of code had used uniqueNum in the original code, getCurrentThreadId() would always have returned "the next ID to be assigned" instead of "the ID assigned for the current thread".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM