This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
Thread closed
When accessing shared data, synchronization is usually used. If you want to avoid synchronization, you do not provide shared data. If data is accessed only in a single thread, synchronization is not required, a technique called thread closure, and it is one of the easiest ways to achieve thread-safety. Thread-safety is automatically implemented when an object is enclosed within a thread, even if the enclosed object itself is not safe. There are three main ways to implement threads.
1. Ad-hoc threads are closed
Ad-hoc means that maintaining thread closure is implemented and maintained by the program itself. Ad-hoc is vulnerable because it doesn’t have a language feature, such as visibility modifiers or local variables, that can seal an object to a particular thread.
2. The stack closed
Stack closure is simply understood through local variables to achieve thread closure, multiple threads access the object of the same method, the local variables inside the method will be copied to each thread stack, only the current thread can access, do not interfere with each other. So local variables are not shared by multiple threads.
Example:
public class ThreadTest { private int num; public void test(int key){ int flag=0; for(int i=0; i<key; i++){ flag=flag+1; num=num+1; } System.out.println(Thread.currentThread().getName()+"num"+num); System.out.println(Thread.currentThread().getName()+"flag"+flag); } public static void main(String[] args) { ThreadTest threadTest=new ThreadTest(); Thread thread1=new Thread(new Runnable() { @Override public void run() { threadTest.test(10); }}); thread1.start(); Thread thread2=new Thread(new Runnable() { @Override public void run() { threadTest.test(9); }}); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } thread2.start(); }} # thread_0num10 thread_0flag10 thread_1flag9Copy the code
As can be seen from the example, there is a global variable num on the class, and a local variable flag in the method. Start two threads to call this method, and it is found that the result of num is the sum of the results of the two threads, while flag does not interfere with each other, so the local variable is not shared by multiple threads.
3.ThreadLocal
A more formal approach to maintaining thread closure is to use ThreadLocal. ThreadLocal provides get and set methods that have a separate copy for each thread that uses the variable, so GET always returns the value set by the current thread when it calls the set.
ThreadLocal is typically used to prevent mutable singleton variables or global variables from being shared. For example, a single-threaded application might maintain a global database Connection and initialize this object at program startup to avoid passing a Connection object for every method called. Since JDBC connection objects are not necessarily thread-safe, when multithreaded applications use global variables without coordination, each thread will have its own connection by storing JDBC connections in a ThreadLocal.
Examples of ThreadLocal code:
Public class Demo7 {/** threadLocal, each thread has a copy, */ public static ThreadLocal<String> value = new ThreadLocal<>(); /** * threadLocal test ** @throws Exception */ public void threadLocalTest() throws Exception Value.set (" This is 123 set by the main thread "); String v = value.get(); System.out.println(" the main thread gets the value before thread 1 executes: "+ v); new Thread(new Runnable() { @Override public void run() { String v = value.get(); System.out.println(" thread 1 fetch: "+ v); // set threadLocal value.set(" this is 456 set by thread 1 "); v = value.get(); System.out.println(" after resetting, thread 1 fetched: "+ v); System.out.println(" thread 1 completes execution "); } }).start(); Thread.sleep(5000L); V = value.get(); System.out.println(" after thread 1 executes, the main thread gets the value: "+ v); } public static void main(String[] args) throws Exception { new Demo7().threadLocalTest(); }} # thread 1 = 123; thread 1 = 123; thread 1 = 123Copy the code
From the code examples, you can see that the execution results of the main thread and child threads do not interfere with each other. ThreadLocal can be used when a frequently executed operation requires a temporary object, such as a buffer, and you want to avoid reassigning the temporary object each time it is executed. ThreadLocal provides a separate copy for each thread.
Highlights from the past
Analysis of Synchronized principle
Let small application perfect support Markdown, the most detailed tutorial to come
On the way of learning, we always need like-minded people to discuss and move forward together, pay attention to me and study together