每一个当前线程中都有一个ThreadLocal,这个ThreadLocal是与其余线程分开的。存储在ThreadLocal是数据,对于线程内共享是共享的,线程外(其它线程)是独立的。java
import java.util.HashMap; import java.util.Map; import java.util.Random; /** * 线程数据共享demo(线程内共享变量,线程外独立) * * 方法一:定义Map<Thread, Integer>对象,存储共享数据 */ public class ThreadScopeShareData { private static int data = 0; // 存储每一个线程中独立的数据 private static Map<Thread, Integer> threadData = new HashMap<Thread, Integer>(); public static void main(String[] args) { for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { data = new Random().nextInt(); threadData.put(Thread.currentThread(), data); // 将当前线程的线程和线程共享数据存入map中 System.out.println(Thread.currentThread().getName() + "has put data:" + data); new A().get(); // 调用模块一的方法 new B().get(); // 调用模块二的方法 } }).start(); } } // 模块一 static class A { public void get() { int data = threadData.get(Thread.currentThread()); // 从map中获取当前线程数据对象 System.out.println("A from " + Thread.currentThread().getName() + " get data:" + data); } } // 模块二 static class B { public void get() { int data = threadData.get(Thread.currentThread()); // 从map中获取当前线程数据对象 System.out.println("B from " + Thread.currentThread().getName() + " get data:" + data); } } }
import java.util.Random; /** * 线程数据共享demo(ThreadLocal:线程内共享变量,线程外独立) * * 场景一:线程内只需共享一个变量 * 方法二:使用ThreadLocal */ public class ThreadLocalTest1 { // 建立一个ThreadLocal对象 private static ThreadLocal<Integer> x = new ThreadLocal<Integer>(); public static void main(String[] args) { for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(); // 生成当前线程的数据 System.out.println(Thread.currentThread().getName() + "has put data:" + data); x.set(data); // 将当前线程的数据放入ThreadLocal new A().get(); // 调用模块一的方法 new B().get(); // 调用模块二的方法 } }).start(); } } // 模块一 static class A { public void get() { int data = x.get();// 获取当前线程的数据 System.out.println("A from " + Thread.currentThread().getName() + " get data:" + data); } } // 模块二 static class B { public void get() { int data = x.get();// 获取当前线程的数据 System.out.println("B from " + Thread.currentThread().getName() + " get data:" + data); } } }
import java.util.Random; /** * 线程数据共享demo(ThreadLocal:线程内共享变量,线程外独立) * * 场景二:线程内需共享多个变量 * 方法一:定义一个共享数据结构的类,将共享数据结构类做为ThreadLocal的泛型 */ public class ThreadLocalTest2 { // 建立一个ThreadLocal对象,并将MyThreadScopeData1座位泛值类型 private static ThreadLocal<MyThreadScopeData1> myThreadScopeData = new ThreadLocal<MyThreadScopeData1>(); public static void main(String[] args) { for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + "has put data:" + data); // 设置当前线程的数据对象,而且将对象放置在ThreadLocal对象中 MyThreadScopeData1 myData = new MyThreadScopeData1(); myData.setName(Thread.currentThread().getName()); myData.setAge(data); myThreadScopeData.set(myData); new A().get(); new B().get(); } }).start(); } } // 模块一 static class A { public void get() { MyThreadScopeData1 myData = myThreadScopeData.get(); // 获取当前线程数据对象 System.out.println("A from " + Thread.currentThread().getName() + ": getName()=" + myData.getName() + ", getAge()=" + myData.getAge()); } } // 模块二 static class B { public void get() { MyThreadScopeData1 myData = myThreadScopeData.get(); // 获取当前线程数据对象 System.out.println("B from " + Thread.currentThread().getName() + ": getName()=" + myData.getName() + ", getAge()=" + myData.getAge()); } } } /** * 定义共享数据结构类 */ class MyThreadScopeData1 { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
import java.util.Random; /** * 线程数据共享demo(ThreadLocal:线程内共享变量,线程外独立) * * 场景二:线程内需共享多个变量 * 方法二:定义一个共享数据结构的类,ThreadLocal对象放入共享数据结构的类中,在共享数据结构类中存储全部线程的共享数据 */ public class ThreadLocalTest3 { public static void main(String[] args) { for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + "has put data:" + data); // 设置当前线程的数据对象,先取出MyThreadScopeData的实例,再设置值 MyThreadScopeData.getThreadDataInstance().setName(Thread.currentThread().getName()); ; MyThreadScopeData.getThreadDataInstance().setAge(data); new A().get(); // 调用模块一的方法 new B().get(); // 调用模块二的方法 } }).start(); } } // 模块一 static class A { public void get() { MyThreadScopeData myData = MyThreadScopeData.getThreadDataInstance(); // 获取当前线程的共享数据对象 System.out.println("A from " + Thread.currentThread().getName() + ": getName()=" + myData.getName() + ", getAge()=" + myData.getAge()); } } // 模块二 static class B { public void get() { MyThreadScopeData myData = MyThreadScopeData.getThreadDataInstance(); // 获取当前线程的共享数据对象 System.out.println("B from " + Thread.currentThread().getName() + ": getName()=" + myData.getName() + ", getAge()=" + myData.getAge()); } } } /** * 定义共享数据结构类,类中定义ThreadLocal对象,将全部线程的共享数据都放置这个类的这个对象中 */ class MyThreadScopeData { private String name; private int age; // private static MyThreadScopeData instance = null; private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>(); // 步骤一、构建私有构造函数,不容许外部经过new建立 private MyThreadScopeData() { }; // 步骤二、开放获取实例的方法 public static MyThreadScopeData getThreadDataInstance() { MyThreadScopeData instance = map.get(); if (null == instance) { instance = new MyThreadScopeData(); map.set(instance); } return instance; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
在线程内需共享多个变量中推荐使用方法二,这种将ThreadLocal对象定义在共享数据结构类的方式将使代码更加优雅。数据结构