这是使用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。
先谢谢。
答案 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