每一個當前線程中都有一個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對象定義在共享數據結構類的方式將使代碼更加優雅。數據結構