ThreadLocal深入理解

来源:互联网 发布:r语言高性能编程 pdf 编辑:程序博客网 时间:2024/06/03 19:09

JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量

在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。

我们来看一个示例吧

import java.util.Random;/** * ThreadLocal的深入理解 *  * @author chinoukin * */public class ThreadLocalTest {private static ThreadLocal<Integer> x = new ThreadLocal<>();public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {int data = new Random().nextInt();x.set(data);System.out.println(Thread.currentThread().getName() + "放入id:" + data);MyLocalData myLocalData = MyLocalData.getMyLocalDataInstance();myLocalData.setId(data);myLocalData.setName("张三丰");new TestA().get();new TestB().get();}}, "线程1").start();new Thread(new Runnable() {@Overridepublic void run() {int data = new Random().nextInt();x.set(data);System.out.println(Thread.currentThread().getName() + "放入id:" + data);MyLocalData myLocalData = MyLocalData.getMyLocalDataInstance();myLocalData.setId(data);myLocalData.setName("张无忌");new TestA().get();new TestB().get();}}, "线程2").start();}static class TestA {public void get() {int data = x.get();MyLocalData myLocalData = MyLocalData.getMyLocalDataInstance();System.out.println("A从" + Thread.currentThread().getName() + "中拿出id:" + data);System.out.println("A从" + Thread.currentThread().getName() + "中拿出name:" + myLocalData.getName());}}static class TestB {public void get() {int data = x.get();MyLocalData myLocalData = MyLocalData.getMyLocalDataInstance();System.out.println("B从" + Thread.currentThread().getName() + "中拿出id:" + data);System.out.println("B从" + Thread.currentThread().getName() + "中拿出name:" + myLocalData.getName());}}}/** * 线程数据类(ThreadLocal) 每一个线程最多只有一个实例,保证每个线程自己数据类实例不会被其他线程破坏 *  * @author chinoukin * */class MyLocalData {private MyLocalData() {}private static ThreadLocal<MyLocalData> map = new ThreadLocal<>();public static MyLocalData getMyLocalDataInstance() {MyLocalData myLocalData = map.get();if (myLocalData == null) {myLocalData = new MyLocalData();map.set(myLocalData);}return myLocalData;}private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

运行结果:

线程1放入id:569578798线程2放入id:-185649376A从线程1中拿出id:569578798A从线程2中拿出id:-185649376A从线程1中拿出name:张三丰A从线程2中拿出name:张无忌B从线程2中拿出id:-185649376B从线程2中拿出name:张无忌B从线程1中拿出id:569578798B从线程1中拿出name:张三丰
通过执行结果我们可以发现,每个线程自己的ThreadLocal变量都是独立的,线程间互补干扰。





原创粉丝点击