Java multithreading -- ThreadLocal Introduction
In multi-threaded development, we often encounter calling a public attribute in the run method. Because each start operation creates a thread
All threads share one attribute. When any thread changes the value of this attribute, this attribute will be changed in the following usage process.
Many unexpected events occur, which is called thread unsafe. Here is an example to illustrate this problem.
package com.bird.concursey;import java.util.Date;import java.util.concurrent.TimeUnit;public class UnsafeTask implements Runnable{private Date startDate;@Overridepublic void run() {startDate = new Date();System.out.println("start thread " + Thread.currentThread().getId() + " " + startDate);try {TimeUnit.SECONDS.sleep((int)Math.rint(Math.random() * 10));} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread finish " + Thread.currentThread().getId() + " " + startDate);}public static void main(String[] args) {UnsafeTask task = new UnsafeTask();for(int i = 0; i < 10; i++) {Thread thread = new Thread(task);thread.start();try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}}}}
Here we have created ten sub-threads in the main thread, and each thread will instantiate this date, then you will be surprised to find that when all the threads
After running, their end time is the same. The running result is as follows.
start thread 8 Tue Sep 16 20:21:50 CST 2014start thread 9 Tue Sep 16 20:21:52 CST 2014start thread 10 Tue Sep 16 20:21:54 CST 2014start thread 11 Tue Sep 16 20:21:56 CST 2014start thread 12 Tue Sep 16 20:21:58 CST 2014Thread finish 10 Tue Sep 16 20:21:58 CST 2014Thread finish 11 Tue Sep 16 20:21:58 CST 2014Thread finish 8 Tue Sep 16 20:21:58 CST 2014start thread 13 Tue Sep 16 20:22:00 CST 2014Thread finish 9 Tue Sep 16 20:22:00 CST 2014start thread 14 Tue Sep 16 20:22:02 CST 2014start thread 15 Tue Sep 16 20:22:04 CST 2014Thread finish 14 Tue Sep 16 20:22:04 CST 2014start thread 16 Tue Sep 16 20:22:06 CST 2014Thread finish 12 Tue Sep 16 20:22:06 CST 2014start thread 17 Tue Sep 16 20:22:08 CST 2014Thread finish 16 Tue Sep 16 20:22:08 CST 2014Thread finish 13 Tue Sep 16 20:22:08 CST 2014Thread finish 15 Tue Sep 16 20:22:08 CST 2014Thread finish 17 Tue Sep 16 20:22:08 CST 2014
The main reason is that all threads share one attribute and one thread changes its value. As a result, all subsequent calls are actually the value of a variable.
The expectation is that each Thread has its own attribute value and everyone is independent. What should we do.
package com.bird.concursey;import java.util.Date;import java.util.concurrent.TimeUnit;public class SafeTask implements Runnable {private static ThreadLocal
startDate = new ThreadLocal
() {protected Date initialValue() {return new Date();};};@Overridepublic void run() {System.out.println("start thread " + Thread.currentThread().getId()+ " " + startDate.get());try {TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread finish " + Thread.currentThread().getId()+ " " + startDate.get());}public static void main(String[] args) {SafeTask task = new SafeTask();for (int i = 0; i < 10; i++) {Thread thread = new Thread(task);thread.start();try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}}}}
This is the correct code. It is mainly added to the ThreadLocal class. The main purpose is to ensure that every time the thread is enabled
Will call his initvalue method to pay an initial value for this attribute, and then each thread will maintain this value by itself, each thread is independent,
We can get the corresponding value through the get method, of course, it also provides the set method to change its value, or remove, etc. Anyway, it is the thread security
All.