ThreadLocal的作用
ThredLocal是多线程中为了保证线程安全而提供的工具类,它可以代表一个线程局部变量,该类支持泛型。
- 每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。
- 将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中,然后在线程执行的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。
ThreadLocal的使用场景
如果访问的资源无限且需要同步,使用该资源不会影响别的线程,每个线程对应一个实例)的对象的访问,那就可以使用ThreadLocal来作为线程局部变量。
ThreadLocal与volatile的区别
volatile和ThreadLocal看起来都是用于变量,但volatile修饰的变量始终只有一份,volatile的作用和同步机制一样,如果只是对一两个实例变量进行线程同步就没必要使用synchronized,使用volatile更方便。但是ThreadLocal是在每一个线程中都存放了一份资源,每个线程各玩各的,互不影响。
ThreadLocal的使用方法
- set():为ThreadLocal实例设置值
- get():获取ThreadLocal实例对应的值
- remove():移除ThreadLocal实例对应的值
- 以上方法是最基本的,如果泛型是String,还可以使用String的方法。
ThreadLocal实例
public class ThreadLocalDemo {
//创建ThreadLocal实例
ThreadLocal<String> thr = new ThreadLocal();
//初始化Threadlocal实例的数据
public ThreadLocalDemo(String thr) {
this.thr.set(thr);
}
public static void main(String[] args) {
ThreadLocalDemo t = new ThreadLocalDemo("FUCK");
Test tes = new Test(t);
Test tes2 = new Test(t);
new Thread(tes,"A线程-").start();
new Thread(tes,"B线程-").start();
}
}
//测试ThreadLocal线程
class Test implements Runnable{
private ThreadLocalDemo tld;
public Test(ThreadLocalDemo tld) {
this.tld = tld;
}
@Override
public void run() {
for(int i=0; i < 6; i++) {
tld.thr.set(i + "");
//i==5将ThreadLocal实例的值设置为线程名
if(i == 3)
tld.thr.set(Thread.currentThread().getName());
try {
Thread.sleep(1);//当前线程让出执行权
} catch (InterruptedException e) {e.printStackTrace();}
System.out.println(Thread.currentThread().getName() + tld.thr.get());
}
}
}
- 实例解析:在测试ThreadLocal的线程中,当i==3时,将ThreadLocal实例的值设置为当前线程名,所以会看到A线程与B线程的ThreadLocal是不同的,互不影响。