If you define a single-instance Java Bean, it has several attributes, but one is NOT thread-safe, such as hashmap. It happens that you do not need to share this attribute in different threads, that is, this attribute does not have the meaning of cross-thread. So do not use sychronize as complicated. threadlocal will be a good choice.
For example:
Import java. util. hashmap;
Public class treadlocaltest {
Static threadlocal @ Override
Protected hashmap initialvalue (){
System. Out. println (thread. currentthread (). getname () + "initialvalue ");
Return new hashmap ();
}
};
Public void run (){
Thread [] runs = new thread [3];
For (INT I = 0; I <runs. length; I ++ ){
Runs [I] = new thread (New T1 (I ));
}
For (INT I = 0; I <runs. length; I ++ ){
Runs [I]. Start ();
}
}
Public static class T1 implements runnable {
Int ID;
Public T1 (INT id0 ){
Id = id0;
}
Public void run (){
System. Out. println (thread. currentthread (). getname () + ": Start ");
Hashmap map = map0.get ();
For (INT I = 0; I <10; I ++ ){
Map. Put (I, I + id * 100 );
Try {
Thread. Sleep (100 );
} Catch (exception ex ){
}
}
System. Out. println (thread. currentthread (). getname () + ':' + map );
}
}
/**
* Main
* @ Param ARGs
*/
Public static void main (string [] ARGs ){
Treadlocaltest test = new treadlocaltest ();
Test. Run ();
}
}
Output explanation;
Thread-1: Start
Thread-2: Start
Thread-0: Start
Thread-2initialValue
Thread-1initialValue
Thread-0initialValue
Thread-1: {0 = 100, 1 = 101, 2 = 102, 3 = 103, 4 = 104, 5 = 105, 6 = 106, 7 = 107, 8 = 108, 9 = 109}
Thread-2: {0 = 200, 1 = 201, 2 = 202, 3 = 203, 4 = 204, 5 = 205, 6 = 206, 7 = 207, 8 = 208, 9 = 209}
Thread-0: {0 = 0, 1 = 1, 2 = 2, 3 = 3, 4 = 4, 5 = 5, 6 = 6, 7 = 7, 8 = 8, 9 = 9}
Although map0 is a static variable, initialvalue is called three times. It is found through debug that initialvalue is initiated from map0.get. In addition, each thread has its own map, although they execute at the same time.
Go to theadlocal code and find the following snippets;
Public t get (){
Thread t = thread. currentthread ();
Threadlocalmap map = getmap (t );
If (map! = NULL ){
Threadlocalmap. Entry E = map. getentry (this );
If (E! = NULL)
Return (t) E. value;
}
Return setinitialvalue ();
}
This indicates that threadlocal does have only one variable, but it contains a map internally and retains an entry for each thread. If the corresponding thread does not exist, initialvalue is called.
Threadlocal usage and implementation principle