ThreadLocal为解决多线程的并发问题提供了一种新的思路,使用这个工具类可以优美的编写出多线程程序。
ThreadLocal他不是一个线程,而是线程的一个本地化对象。当工作于多个线程的对象使用ThreadLocal维护变量时,ThreadLocal为每个使用改变量的线程分配一个独立的变量副本,所以每一个线程可以独立的改变自己的副本,而不会影响其他线程的对应的副本。
ThreadLocal接口有四个方法 - void set(Object value)设置当前的线程局部变量的值
- public Obejct get()返回当前的线程所对应的线程局部变量的值
- public void remove()将当前的线程的局部变量的值删除掉
- protected Object initialValue()返回该线程局部变量的初始值,默认实现直接返回一个null。
ThreadLocal如何做到为每一个线程维护一份独立的变量副本呢?实现的思路是:在
ThreadLocal类中有个Map,用于存储每一个线程的变量副本,Map中元素的key为线程对象,而value对应线程的变量副本。
ThreadLocal如何做到为每一个线程维护一份独立的变量副本呢?实现的思路是:在
ThreadLocal类中有个Map,用于存储每一个线程的变量副本,Map中元素的key为线程对象,而value对应线程的变量副本。
下面直接上代码看实例:
public class SequenceNumber
{private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){public Integer initialValue(){return 0;}};public int getNextNum(){seqNum.set(seqNum.get()+1);return seqNum.get();}public static void main (String[] args) throws java.lang.Exception{SequenceNumber sn = new SequenceNumber();TestClient t1 = new TestClient(sn);TestClient t2 = new TestClient(sn);TestClient t3 = new TestClient(sn);t1.start();t2.start();t3.start();}private static class TestClient extends Thread{private SequenceNumber sn;public TestClient(SequenceNumber sn){this.sn = sn;}public void run (){for (int i= 0;i<3 ;i++ ) {System.out.println("thread["+ Thread.currentThread().getName()+"]sn["+ sn.getNextNum()+"]");}}}
}
运行后的输出如下:
从结果可以看出:每个线程所产生的程序虽然共享同一个
SequenceNumber 实例 ,但是他们呢并没有相互干扰的情况出现,而是各自产生独立的序列号,这是因为我我们通过<h3>ThreadLocal为每一个线程提供了独立的副本。</h3>