ThreadLocal学习资料

下面的这一段代码运行起来,就会发生线程安全问题:

启动两个线程,同时去修改 name 属性值。

package com.liwei.thread;

/**
 * 下面的代码演示了线程安全发生的由来
 * 
 * @author Administrator
 * 
 */
public class ThreadLocalTest implements Runnable {
    private int i = 0;
    private String name = null;

    @Override
    public void run() {
        for (; i < 10; i++) {
            name = Thread.currentThread().getName();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" + name);
        }
    }

    public static void main(String[] args) {
        ThreadLocalTest tlt = new ThreadLocalTest();
        Thread t1 = new Thread(tlt, "AAA");
        Thread t2 = new Thread(tlt, "BBB");
        t1.start();
        t2.start();
    }
}

为了解决这个问题,我们给代码加上同步监视器,如下:

package com.liwei.thread;

/**
 * 下面的代码演示了线程安全发生的由来
 * 
 * @author Administrator
 * 
 */
public class ThreadLocalTest implements Runnable {
    private int i = 0;
    private String name = null;

    @Override
    public void run() {
        for (; i < 10000; i++) {
            synchronized (this) {
                name = Thread.currentThread().getName();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + name);
            }
        }
    }

    public static void main(String[] args) {
        ThreadLocalTest tlt = new ThreadLocalTest();
        Thread t1 = new Thread(tlt, "AAA");
        Thread t2 = new Thread(tlt, "BBB");
        t1.start();
        t2.start();
    }
}

 下面,我们的主角就要登场了,让我们来看看 ThreadLocal 的威力:

package com.liwei.thread;

/**
 * 下面的代码演示了线程安全发生的由来
 * 
 * @author Administrator
 * 
 */
public class ThreadLocalTest2 implements Runnable {

    private int i = 0;
    private ThreadLocal<String> threadLocal = new ThreadLocal<>();

    @Override
    public void run() {
        for (; i < 100; i++) {
            threadLocal.set(Thread.currentThread().getName());

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" + threadLocal.get());

        }
    }

    public static void main(String[] args) {
        ThreadLocalTest2 tlt = new ThreadLocalTest2();
        Thread t1 = new Thread(tlt, "CCC");
        Thread t2 = new Thread(tlt, "DDD");
        t1.start();
        t2.start();
    }
}

我们通过看源码可以知道:ThreadLocalMap 以当前的 ThreadLocal 作为键。

参考资料:

ThreadLocal-分析-总结 - 洞玄 - ITeye技术网站
http://mxdba.iteye.com/blog/777716

深入浅出ThreadLocal - Java综合 - Java - ITeye论坛
http://www.iteye.com/topic/757478

原文地址:https://www.cnblogs.com/liweiwei1419/p/4314016.html