TreadLocal

来源:互联网 发布:新浪域名国外的 编辑:程序博客网 时间:2024/05/22 16:06

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在类间如何做转换