java中的ThreadLocal

时间:2014-05-12 01:12:37

标签: java multithreading concurrency

这是使用ThreadLocal的java doc中的示例。

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

我不明白为什么我们在这里使用threadlocal。是不是AtomicInteger已经线程安全?

将代码改为此怎么办?

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

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

我也不明白这意味着什么:

这些变量与普通对象的不同之处在于,访问一个变量的每个线程(通过其get或set方法)都有自己独立初始化的变量副本。

那么,ThreadLocal(内部)是否为每个线程保存一个整数数组? 实践中的Java_concurrency提到我们可以将threadLocal视为Map。

先谢谢。

1 个答案:

答案 0 :(得分:3)

注意所有这些变量是如何声明为static的。这意味着通常只有一个。

为了使threadId线程特定,我们使用threadlocal。这意味着每个线程现在只有一个实例,而不是有一个实例。

在您的版本中,每次调用get()时,它都会返回不同的数字。

在原始版本中,第一次调用get时,它将自动初始化并将值保存在线程上。每次后续调用都会返回此值以获取该线程。

你的代码

//in thread 0
ThreadId.get() //return 0
//in thread 1
ThreadId.get() //return 1
//in thread 0
ThreadId.get() //return 2
//in thread 1
ThreadId.get() //return 3
//in thread 0
ThreadId.get() //return 4

原始代码

//in thread 0
ThreadId.get() //return 0
//in thread 1
ThreadId.get() //return 1
//in thread 0
ThreadId.get() //return 0
//in thread 1
ThreadId.get() //return 1
//in thread 0
ThreadId.get() //return 0