ThreadLocal由浅入深

我们已经知道在并发中,可以使用volatile保证变量的可见性,也可以通过synchronize保证代码块的原子性,它们解决并发都是同一个思想,控制互斥资源的访问先后顺序。

而ThreadLocal则采用隔离数据的方式,使得每个线程都具备一份副本,互不影响。

package com.mjw.java.threadlocal;

public class ThreadLocalDemo {
    static class MyThread implements Runnable {
        private String name;

        public MyThread(String name) {
            this.name = name;
        }
        public void run() {
            noThreadLocal = name;
//          ThreadLocalDemo.threadLocal.set(name);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(noThreadLocal);
//          System.out.println(ThreadLocalDemo.threadLocal.get());
        }
    }
    private static String noThreadLocal;
    private static ThreadLocal<String> threadLocal = new ThreadLocal();
    public static void main(String[] args) {
        /**
         * 3个线程同时使用一个static String
         * 3个线程同时使用一个ThreadLocal
         */
        Thread t1 = new Thread(new MyThread("mao"));
        Thread t2 = new Thread(new MyThread("li"));
        Thread t3 = new Thread(new MyThread("wang"));

        t1.start();
        t2.start();
        t3.start();
    }
}

可以先想一下这段程序的运行结果~~~~~~~~
在这里插入图片描述
如果三个线程同时修改一个静态变量,那他们会互相影响,我们最后一个线程启动时,把静态变量修改成wang,等到线程1、2使用时,就会发现值被修改了,存在线程问题。
如果我们想让他们互不影响,那就可以使用ThreadLocal
如果为了方便理解,我们可以把ThreadLocal当作是一个Map,只是默认帮我们把当前线程ID作为key。

==========================================

但是实际上,ThreadLocal并不是一个Map,这个Map类是ThreadLocal的一个内部类ThreadLocalMap
ThreadLocal由浅入深_第1张图片
Thread类中有一个成员变量的类型就是ThreadLocalMap
ThreadLocal由浅入深_第2张图片

	ThreadLocalDemo.threadLocal.set(name);
	// ThreadLocal set方法
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }`

通过跟读ThreadLocal的set方法,我们可以发现,会为每个线程的threadLocals都创建一个map,用于存放当前线程的key,value。在我的例子中,key为threadLocal,value分别为“mao”,“li”,“wang”。
ThreadLocal由浅入深_第3张图片
三个线程对应三个map(threadLocals)对应一个threadLocal。
我们开始时认为key是线程id是错误的,key是ThreadLocal实例,因为在不同的map中,所以才能根据相同的key拿到不同的值

你可能感兴趣的:(笔记,多线程,thread,java,编辑器)