Use: Transaction managers in databases are commonly used, and all operations are performed on the same data. Develop and program from the system perspective.
The first method is rough.
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(){ public void run(){ data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has put data :"+data); threadData.put(Thread.currentThread(),data); new A().get(); new B().get(); } }).start(); } } static class A{ public void get(){ data = threadData.get(Thread.currentThread()); System.out.println("A from "+ Thread.currentThread().getName()+" get data :"+data); } } static class B{ public void get(){ data = threadData.get(Thread.currentThread()); System.out.println("B from "+ Thread.currentThread().getName()+" get data :"+data); } }}
Method 2: threadlocal, which is equivalent to a map
public class ThreadLocalTest { static final ThreadLocal<Integer> x = new ThreadLocal<Integer>(); public static void main(String[] args){ for (int i = 0; i < 2; i++) { new Thread(new Runnable(){ public void run(){ int data = new Random().nextInt()/10000000; System.out.println(Thread.currentThread().getName() + " has put data :"+data); x.set(data); 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); } }}
Method 3: operate multiple data types, not just basic data types. It can be integrated into an object and then set this object to threadlocal.
public class ThreadLocalTest { private static final ThreadLocal<Integer> x = new ThreadLocal<Integer>(); private static final ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>(); public static void main(String[] args){ for (int i = 0; i < 2; i++) { new Thread(new Runnable(){ public void run(){ int data = new Random().nextInt()/10000000; System.out.println(Thread.currentThread().getName() + " has put data :"+data); x.set(data); MyThreadScopeData myData = new MyThreadScopeData(); myData.setName(" name "+data); myData.setAge(data); myThreadScopeData.set(myData); 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); MyThreadScopeData myData = myThreadScopeData.get(); System.out.println("A from "+ Thread.currentThread().getName()+" getMydata :"+myData.getName()+","+myData.getAge()); } } static class B{ public void get(){ int data = x.get(); System.out.println("B from "+ Thread.currentThread().getName()+" get data :"+data); MyThreadScopeData myData = myThreadScopeData.get(); System.out.println("B from "+ Thread.currentThread().getName()+" getMydata :"+myData.getName()+","+myData.getAge()); } }} class MyThreadScopeData{ 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; } }
Method 4: an elegant solution, similar to the singleton mode. The thradlocal class is placed behind the object class, and the design is also handed over to the object class. The caller does not need to care about the design of the object class, but only needs to get to the Instance Object of the object class, within the same thread, instance objects of the object class are called in any place, and the operation data is the same, which achieves data sharing in the thread. This processing method is a good embodiment of the object-oriented thinking.
Strust2 is also designed in this way.
public class ThreadLocalTest { private static final ThreadLocal<Integer> x = new ThreadLocal<Integer>(); private static final ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>(); public static void main(String[] args){ for (int i = 0; i < 2; i++) { new Thread(new Runnable(){ public void run(){ int data = new Random().nextInt()/10000000; System.out.println(Thread.currentThread().getName() + " has put data :"+data); x.set(data); MyThreadScopeData.getThreadInstance().setName(" name "+data); MyThreadScopeData.getThreadInstance().setAge(data); 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); MyThreadScopeData myData = MyThreadScopeData.getThreadInstance(); System.out.println("A from "+ Thread.currentThread().getName()+" getMydata :"+myData.getName()+","+myData.getAge()); } } static class B{ public void get(){ int data = x.get(); System.out.println("B from "+ Thread.currentThread().getName()+" get data :"+data); MyThreadScopeData myData = MyThreadScopeData.getThreadInstance(); System.out.println("B from "+ Thread.currentThread().getName()+" getMydata :"+myData.getName()+","+myData.getAge()); } }} class MyThreadScopeData{ private MyThreadScopeData(){}; private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>(); public static MyThreadScopeData getThreadInstance(){ MyThreadScopeData instance = map.get(); if(instance == null){ instance = new MyThreadScopeData(); map.set(instance); } return instance; } 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; } }
Use the threadlocal class:
Similar to a stack mechanism, different threads have different records. For a long time, the more accumulated, the clean () method is provided for cleanup. Of course, it can be automatically recycled internally, so you don't have to worry about overflow if you don't handle it yourself. When the thread completes, the reference of the corresponding instance object will be automatically reclaimed. If there are records in the same thread in different threadlocal objects, the records in these different threadlocal objects will be recycled after the thread completes processing, unless the instance object corresponding to this thread has other operations associated with the thread. Query the JDK documentation in detail.
Q: How do I control the thread death status?