ThreadLocal 实现线程范围内的共享变量,当多线程过程中,容易出现共享数据被别的线程操作,导致脏数据的发生
一:多线程导致的共享变量脏数据例子
public class ThreadLocalTest { private static int data; public static void main(String[] args){ new Thread(){ @Override public void run(){ data= new Random().nextInt(); System.out.println(Thread.currentThread().getName()+",put data:"+data); new Car().getData(); new Birck().getData(); } }.start(); new Thread(){ @Override public void run(){ data= new Random().nextInt(); System.out.println(Thread.currentThread().getName()+",put data:"+data); new Car().getData(); new Birck().getData(); } }.start(); } static class Car{ public void getData(){ System.out.println(Thread.currentThread().getName()+",A get data:"+data); } } static class Birck{ public void getData(){ System.out.println(Thread.currentThread().getName()+",B get data:"+data); } } }
返回结果
线程0存放的数据是 -1551246102, A获取的数据变成了-784747522,获取到了线程1的数据,脏数据就产生了;
二:使用ThreadLocal
public class ThreadLocalTest { private static ThreadLocal<Integer> threadLocal=new ThreadLocal<Integer>(); public static void main(String[] args) { for (int i = 0; i < 2; i++) new Thread() { @Override public void run() { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + ",put data:" + data); threadLocal.set(data); new Car().getData(); new Birck().getData(); } }.start(); } static class Car{ public void getData(){ System.out.println(Thread.currentThread().getName()+",A get data:"+threadLocal.get()); } } static class Birck{ public void getData(){ System.out.println(Thread.currentThread().getName()+",B get data:"+threadLocal.get()); } } }
执行结果
可以看到,每个线程都获取到了自己属于自己的数据
三:ThreadLocal在类间如何做转换