ThreadLocal 使用及原理

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。这样就隔离了多个线程对数据的数据共享

当线程并发时,使用ThreadLocal在保证每个线程拥有自己的独立对象,线程间互不影响。

原理:
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。我们自己就可以提供一个简单的实现版本:

区别:
ThreadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别。synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。

使用:
public class MyThreadLocal {
    //定义了一个ThreadLocal变量,用来保存int或Integer数据
    private ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    public Integer getNextNum() {
        //将tl的值获取后加1,并更新设置t1的值
        tl.set(tl.get() + 1);
        return tl.get();
    }
}

* 测试线程
*/
public class TestThread extends Thread {
    private MyThreadLocal tlt = new MyThreadLocal();

    public TestThread(MyThreadLocal tlt) {
        this.tlt = tlt;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName() + "\t" + tlt.getNextNum());
        }
    }
}

public class Test {
    public static void main(String[] args) {
        MyThreadLocal tlt = new MyThreadLocal();
        Thread t1 = new TestThread(tlt);
        Thread t2 = new TestThread(tlt);
        Thread t3 = new TestThread(tlt);
        Thread t4 = new TestThread(tlt);
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}

可以看出,三个线程各自独立编号,互不影响:
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-0 3
Thread-1 3
Thread-2 1
Thread-3 1
Thread-2 2
Thread-3 2
Thread-2 3
Thread-3 3


Process finished with exit code 0


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private static ThreadLocal DATE_FORMAT_NUM  = new ThreadLocal() {  
protected synchronized SimpleDateFormat initialValue() {  
return new SimpleDateFormat("yyyyMMddHHmmss");  
}  
}; 

猜你喜欢

转载自cuityang.iteye.com/blog/2381301