美文网首页爱编程,爱生活
Java Concurrency <ThreadLocal

Java Concurrency <ThreadLocal

作者: 熬夜的猫头鹰 | 来源:发表于2018-06-16 21:58 被阅读21次

Java Concurrency <ThreadLocal>

Java中的ThreadLocal类允许您创建只能由同一个线程读取和写入的变量。 因此,即使两个线程正在执行相同的代码,并且代码对ThreadLocal变量进行了引用,那么两个线程也看不到彼此的ThreadLocal变量。

  • 创建一个ThreadLocal
private ThreadLocal myThreadLocal = new ThreadLocal();

您可以看到,您实例化了一个新的ThreadLocal对象。 这只需要每个线程完成一次。 即使不同的线程执行访问ThreadLococal的相同代码,每个线程都将只看到自己的ThreadLocal实例。 即使两个不同的线程在同一个ThreadLocal对象上设置不同的值,它们也看不到对方的值。

  • 访问ThreadLocal
myThreadLocal.set("A thread local value");

  • 读取数据
String threadLocalValue = (String) myThreadLocal.get();

  • 泛型
private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();

  • 初始化ThreadLocal的值
private ThreadLocal myThreadLocal = new ThreadLocal<String>() {
    @Override protected String initialValue() {
        return "This is the initial value";
    }
};    

DEMO


public class ThreadLocalExample {


    public static class MyRunnable implements Runnable {

        private ThreadLocal<Integer> threadLocal =
               new ThreadLocal<Integer>();

        @Override
        public void run() {
            threadLocal.set( (int) (Math.random() * 100D) );
    
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
    
            System.out.println(threadLocal.get());
        }
    }


    public static void main(String[] args) {
        MyRunnable sharedRunnableInstance = new MyRunnable();

        Thread thread1 = new Thread(sharedRunnableInstance);
        Thread thread2 = new Thread(sharedRunnableInstance);

        thread1.start();
        thread2.start();

        thread1.join(); //wait for thread 1 to terminate
        thread2.join(); //wait for thread 2 to terminate
    }

}

ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本.线程隔离的秘密,就在于ThreadLocalMap这个类。ThreadLocalMap是ThreadLocal类的一个静态内部类,它实现了键值对的设置和获取(对比Map对象来理解),每个线程中都有一个独立的ThreadLocalMap副本,它所存储的值,只能被当前线程读取和修改。ThreadLocal类通过操作每一个线程特有的ThreadLocalMap副本,从而实现了变量访问在不同线程中的隔离。因为每个线程的变量都是自己特有的,完全不会有并发错误。还有一点就是,ThreadLocalMap存储的键值对中的键是this对象指向的ThreadLocal对象,而值就是你所设置的对象了

  • InheritableThreadLocal

InheritableThreadLocal类是ThreadLocal的一个子类。 InheritableThreadLocal不是每个线程在ThreadLocal中具有自己的值,而是授予对线程和该线程创建的所有子线程的值的访问权限。

相关文章

网友评论

    本文标题:Java Concurrency <ThreadLocal

    本文链接:https://www.haomeiwen.com/subject/upxieftx.html