摘要:1.線程范圍內(nèi)共享變量 1.1 前奏:使用一個Map來實現(xiàn)線程范圍內(nèi)共享變量 public class ThreadScopeShareData { static Map<Thread, Integer> dataMap = new HashMap
1.線程范圍內(nèi)共享變量
1.1 前奏:
使用一個Map來實現(xiàn)線程范圍內(nèi)共享變量
public class ThreadScopeShareData { static Map<Thread, Integer> dataMap = 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() { int data = new Random().nextInt(); // 獲取一個隨機整數(shù) System.out.println(Thread.currentThread().getName() + " put data " + data); dataMap.put(Thread.currentThread(), data); new A().get(); new B().get(); } }).start(); } } static class A { public void get() { System.out.println(Thread.currentThread().getName() + " get data " + dataMap.get(Thread.currentThread())); } } static class B { public void get() { System.out.println(Thread.currentThread().getName() + "get data " + dataMap.get(Thread.currentThread())); } } }
1.2 ThreadLocal類實際上就是一種map
/** * ThreadLocal 類 這里ThreadLocal存放一個變量,如果有多個變量, 可以先將多個變量封裝為一個對象 * * @author Administrator * */ public class ThreadLocalTest { static ThreadLocal<Integer> x = new ThreadLocal<>(); // 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(); // 獲取一個隨機整數(shù) System.out.println(Thread.currentThread().getName() + " put data " + data); x.set(data); new A().get(); new B().get(); } }).start(); } } static class A { public void get() { System.out.println(Thread.currentThread().getName() + " get data " + x.get()); } } static class B { public void get() { System.out.println(Thread.currentThread().getName() + "get data " + x.get()); } } }
2.線程范圍內(nèi)共享多個變量,可以將多個變量封裝為一個對象
/** * ThreadLocal 類 這里ThreadLocal存放一個變量,如果有多個變量, 可以先將多個變量封裝為一個對象 * * @author Administrator * */ public class ThreadLocalTest { static ThreadLocal<Integer> x = new ThreadLocal<>(); // 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(); // 獲取一個隨機整數(shù) System.out.println(Thread.currentThread().getName() + " put data " + data); x.set(data); MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();//獲取與線程綁定的對象 myData.setName("name"+data); myData.setAge(data); System.out.println(Thread.currentThread().getName() + " put Object " + "name: "+myData.getName()+","+" age: "+myData.getAge()); new A().get(); new B().get(); } }).start(); } } static class A { public void get() { System.out.println(Thread.currentThread().getName() + " get data " + x.get()); MyThreadScopeData instance = MyThreadScopeData.getThreadInstance(); //直接獲取與該線程相關的對象 System.out.println(Thread.currentThread().getName() + " get Object " + "name: "+instance.getName()+","+" age: "+instance.getAge()); } } static class B { public void get() { System.out.println(Thread.currentThread().getName() + "get data " + x.get()); MyThreadScopeData instance = MyThreadScopeData.getThreadInstance(); //直接獲取與該線程相關的對象 System.out.println(Thread.currentThread().getName() + " get Object " + "name: "+instance.getName()+","+" age: "+instance.getAge()); } } } // 單例 class MyThreadScopeData { //類的實例是與線程相關的,那么類的設計就交由類自身完成,只要調(diào)用自然就是與線程有關的 private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<>(); private MyThreadScopeData() { } public static MyThreadScopeData getThreadInstance() { // 線程間是相互獨立的,這里不需要考慮同步 MyThreadScopeData instance = map.get(); if (instance == null) { instance = new MyThreadScopeData(); map.set(instance); } return instance; } private String name; private Integer age; /** * @return the name */ public String getName() { return name; } /** * @param name * the name to set */ public void setName(String name) { this.name = name; } /** * @return the age */ public Integer getAge() { return age; } /** * @param age * the age to set */ public void setAge(Integer age) { this.age = age; } }
打印結果
Thread-1 put data -723086824
Thread-0 put data 772514756
Thread-1 put Object name: name-723086824, age: -723086824
Thread-0 put Object name: name772514756, age: 772514756
Thread-0 get data 772514756
Thread-1 get data -723086824
Thread-0 get Object name: name772514756, age: 772514756
Thread-1 get Object name: name-723086824, age: -723086824
Thread-0get data 772514756
Thread-1get data -723086824
Thread-0 get Object name: name772514756, age: 772514756
Thread-1 get Object name: name-723086824, age: -723086824
類的實例是與線程相關的,那么類的設計就交由類自身完成,只要調(diào)用自然就是與線程有關的 strust2的主要思想就是這么設計的
參看JAVA API
ThreadLocal有一個 remove()方法
可以移除與該線程相關的變量
remove()
Removes the current thread's value for this thread-local variable.
補充:
虛擬機的對應類 Runtime ,中有一個方法 addShutdownHook(Thread hook)
addShutdownHook(Thread hook)
Registers a new virtual-machine shutdown hook.
例如可以寫一個發(fā)送郵件的線程Thread,當虛擬機掛掉之前會調(diào)用傳入的Thread,發(fā)送一封郵件。
線程中是不是也應該有這種機制,當一個線程掛掉之前可以執(zhí)行一個之前注冊好的事件,或者有一個監(jiān)聽器在監(jiān)聽線程的狀態(tài),從而進行回調(diào)
在獲取到線程掛掉的通知,就可以把該線程相關的變量全部remove獲取clear掉