Java文档中ThreadLocal示例是否正确?getCurrentThreadId返回值存疑
关于UniqueThreadIdGenerator的正确性分析
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() { // uniqueId是正确的?还是uniqueNum? return uniqueId.get(); } } // UniqueThreadIdGenerator
这段代码的getCurrentThreadId()方法返回uniqueId.get()是完全错误的,正确写法应该返回uniqueNum.get(),原因如下:
违背核心设计意图
这个类的目标是为每个线程分配唯一且固定的ID,但uniqueId是全局共享的原子整数,直接返回它的当前值会导致:所有线程调用该方法时拿到的是同一个持续自增的全局值,同一个线程多次调用的结果也会不断变化,完全失去了ThreadLocal“线程隔离”的意义。
而uniqueNum作为ThreadLocal变量,每个线程首次调用uniqueNum.get()时,会触发重写的initialValue()方法,通过uniqueId.getAndIncrement()为该线程生成唯一ID,后续该线程再调用get()都会返回这个固定值,这才符合“每个线程对应唯一ID”的设计需求。实际行为差异对比
- 错误写法(返回uniqueId.get()):线程A第一次调用拿到0,线程B调用拿到1,线程A再次调用可能拿到2,线程间的ID完全混乱,且单个线程的ID不固定。
- 正确写法(返回uniqueNum.get()):线程A第一次调用拿到0,之后每次调用都返回0;线程B第一次调用拿到1,之后每次都返回1,每个线程的ID唯一且固定。
内容的提问来源于stack exchange,提问作者Stephen Qu
相关产品推荐
相关产品推荐

