ThreadLocal: Each thread stores its own local and local areas, similar to containers, in which each thread has a certain storage space.
Common methods get/set/initialValue
The official recommendation is private static
Each thread stores its own data, and changes do not affect other threads
The ThreadLocal subclass InheritableThreadLocal:
Data inherited from context environment
public class my { //Integer initial value is null //private static ThreadLocal<Integer> threadlocal=new ThreadLocal<>(); //To change the initial value, you need to create a subclass of ThreadLocal to override the initial value or use lambda(jdk8) private static ThreadLocal<Integer> threadlocal=new ThreadLocal <Integer>() {//Parent Anonymous Internal Class Rewriting Method protected Integer initialValue() { return 200; } }; //private static ThreadLocal<Integer> threadlocal=new ThreadLocal.withInitial(()->200); public static void main(String[]args) throws InterruptedException { //Get value System.out.println(Thread.currentThread().getName()+"-->"+threadlocal.get()); //Set value threadlocal.set(99); System.out.println(Thread.currentThread().getName()+"-->"+threadlocal.get()); new Thread(new test()).start(); new Thread(new test()).start(); } public static class test implements Runnable { public void run() { threadlocal.set((int)(Math.random()*100)); System.out.println(Thread.currentThread().getName()+"-->"+threadlocal.get()); } } }
Each thread's own data changes do not affect other threads
public class my { private static ThreadLocal<Integer> threadlocal=new ThreadLocal <Integer>() {//Parent Anonymous Internal Class Rewriting Method protected Integer initialValue() { return 1; } }; public static void main(String[]args) throws InterruptedException { for(int i=0;i<5;i++) { new Thread(new test()).start(); } } public static class test implements Runnable { public void run() { //Modifications do not affect other threads Integer left=threadlocal.get(); System.out.println(Thread.currentThread().getName()+"-->"+left); threadlocal.set(left-1); System.out.println(Thread.currentThread().getName()+"Still left"+threadlocal.get()); } } }
Analyse the ThreadLocal operating environment:
public class my { private static ThreadLocal<Integer> threadlocal=new ThreadLocal <Integer>() {//Parent Anonymous Internal Class Rewriting Method protected Integer initialValue() { return 1; } }; public static void main(String[]args) throws InterruptedException { new Thread(new test()).start();//Two printed contents are in different threads //After start(), the thread is converted from main to other threads, so the main thread is in the constructor. } public static class test implements Runnable { public test() { threadlocal.set(100); //It belongs to the main thread, and modifications do not affect threads within the start System.out.println(Thread.currentThread().getName()+"-->"+threadlocal.get()); } public void run() { System.out.println(Thread.currentThread().getName()+"Still left"+threadlocal.get()); } } }
Subclass Inheritable ThreadLocal:
public class my { private static ThreadLocal<Integer> threadlocal=new InheritableThreadLocal<>(); public static void main(String[]args) throws InterruptedException { System.out.println(Thread.currentThread().getName()+"-->"+threadlocal.get()); threadlocal.set(2); //This thread is created by the main thread and copies a data of the main thread to this thread. //Give 2 of the main thread to this thread new Thread(()->{ System.out.println(Thread.currentThread().getName()+"-->"+threadlocal.get()); threadlocal.set(200); System.out.println(Thread.currentThread().getName()+"-->"+threadlocal.get()); }).start(); } }