ThreadLocal.get/put
和有什么不同之处?
class ThreadT extends Thread {
private SomeObj obj;
.....
}
我认为,如果我错了请纠正我,这个对象对于每个线程也是不同的。即,如果我们有5个ThreadT对象,那么每个线程都会有5个不同的obj对象。
那么,既然如此,为什么我们需要使用ThreadLocal
呢?
如果我对其中任何一个理解不正确,请纠正我。
ThreadLocal.get/put
和有什么不同之处?
class ThreadT extends Thread {
private SomeObj obj;
.....
}
我认为,如果我错了请纠正我,这个对象对于每个线程也是不同的。即,如果我们有5个ThreadT对象,那么每个线程都会有5个不同的obj对象。
那么,既然如此,为什么我们需要使用ThreadLocal
呢?
如果我对其中任何一个理解不正确,请纠正我。
从文档中可以得知,这个类提供了线程本地变量。这些变量与普通变量不同之处在于,每个访问它的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。
如果您编写的类直接扩展线程,则您的方法将起作用。但是对于需要 ThreadLocal 变量但没有直接访问其 Thread 实例的类呢?
在这种情况下,ThreadLocal 就很有用了。特别是在服务器环境中,大部分时间不直接使用线程的情况下。
final ThreadT tt = new ThreadT();
new Thread() {
public void run() {
tt.set(new Object());
};
}.start();
new Thread() {
public void run() {
Object obj = tt.get();
};
}.start();
我已经写了程序
class ThreadRun implements Runnable {
NumberValue number;
int value;
ThreadRun(NumberValue number,int value) {
this.number=number;
this.value = value;
Thread t = new Thread(this);
t.start();
}
@Override
public void run() {
number = number.getThreadLocal();
number.setId(number.getId()+value);
System.out.println(number.getId());
}
}
public class ThreadTest {
public static void main(String[] args) {
NumberValue number = new NumberValue(1);
new ThreadRun(number, 1);
new ThreadRun(number, 2);
}
}
class NumberValue {
int id;
ThreadLocal<NumberValue> threadLocal = new ThreadLocal<NumberValue>() {
@Override
protected NumberValue initialValue() {
return new NumberValue(id);
}
};
NumberValue(int id) {
this.id = id;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
public NumberValue getThreadLocal() {
return threadLocal.get();
}
}
输出: 2 3 这个输出是我们期望的输出
但是当你注释掉
// number = number.getThreadLocal(); 并运行程序,输出将会是 输出: 3 4 所以当注释掉 // number = number.getThreadLocal(); 时,数据就被破坏了。因此,ThreadLocal会创建 NumberValue 的本地副本。但是当不使用ThreadLocal时,同一个对象实例在线程之间共享,因此数据结果会比实际结果更加错误。
ThreadLocal
不必与线程关联,它可以与任何对象或结构相关联。 - Patashu