Use and learning of synchronize locks in java multithreading, Thread multithreading Learning (2), synchronizethread
Synchronize I understand is to ensure atomicity and consistency in the program, that is, when you have two threads to operate a piece of code at the same time, make sure that the execution of this Code is correct in any State. First, make sure that synchronize is used for the same object and the same lock.
[Java]View plain copy print?
- <Span style = "font-size: 14px;"> public class TraditionalThreadSynchronized {
- Public static void main (String [] args ){
- TraditionalThreadSynchronized test = new TraditionalThreadSynchronized ();
- Test. init (); // create the same object
- }
- Private void init (){
- OutPuter outPuter = new OutPuter ();
- New Thread (new Runnable (){
- @ Override
- Public void run (){
- Try {
- While (true ){
- Thread. sleep (10 );
- OutPuter. outer ("abcdefg ");
- }
- } Catch (InterruptedException e ){
- E. printStackTrace ();
- }
- }
- }). Start (); // thread 1
- New Thread (new Runnable (){
- @ Override
- Public void run (){
- Try {
- While (true ){
- Thread. sleep (10 );
- OutPuter. outer ("123456789 ");
- }
- } Catch (InterruptedException e ){
- E. printStackTrace ();
- }
- }
- }). Start (); // thread 2
- }
- Class OutPuter {
- Public synchronized void outer (String name ){
- For (int I = 0; I <name. length (); I ++ ){
- System. out. print (name. charAt (I ));
- }
- System. out. println ();
- }
- }
- } </Span>
The output result we want to print is abcdefg and 123456789, but the output result is
We found that the printed results are printed alternately by two strings, so this thread is not safe now, so we need to use synchronize to maintain the atomicity of the two threads, next, let's add the synchronize lock to the OutPut method in the above program.
[Java]View plain copy print?
- <Span style = "font-size: 14px;"> class OutPuter {
- Public void outer (String name ){
- Synchronized (name ){
- For (int I = 0; I <name. length (); I ++ ){
- System. out. print (name. charAt (I ));
- }
- System. out. println ();
- }
- }
- } </Span>
We found that this thread is not safe after the lock with the synchronize keyword is applied. Why? The reason lies in the lock name, because one of the two threads is abcdefg and the other is 123456789. The two locks are not a lock at all, so the thread is also insecure, then let's modify the above method.
[Java]View plain copy print?
- <Span style = "font-size: 14px;"> class OutPuter {
- Public void outer (String name ){
- Synchronized (this) {// or create a new lock. You can change this to a lock. Here this refers to the outer object.
- For (int I = 0; I <name. length (); I ++ ){
- System. out. print (name. charAt (I ));
- }
- System. out. println ();
- }
- }
- } </Span>
At this time, we found that the program running above will not have thread security issues.
We can add the above syn to the outer at this time.
[Java]View plain copy print?
- Class OutPuter {
- Public synchronized void outer (String name ){
- For (int I = 0; I <name. length (); I ++ ){
- System. out. print (name. charAt (I ));
- }
- System. out. println ();
- }
- }
This can also achieve thread security, but under normal circumstances, synchronize only needs to be used once in a piece of code, because multiple synchronize may have a deadlock problem!
Now let's modify the OutPuter class above.
[Java]View plain copy print?
- Class OutPuter {
- Public void outer (String name ){
- Synchronized (this ){
- For (int I = 0; I <name. length (); I ++ ){
- System. out. print (name. charAt (I ));
- }
- System. out. println ();
- }
- }
- Public synchronized void outer2 (String name ){
- For (int I = 0; I <name. length (); I ++ ){
- System. out. print (name. charAt (I ));
- }
- System. out. println ();
- }
- Span style = "font-size: 14px;" >}</span>
Then, change outPuter. outer ("123456789") to outPuter. outer2 ("123456789 ")
Can thread security be ensured at this time, that is, will output and output2 be mutually exclusive? Of course, it is also possible, because the two locks at this time also represent the same lock, both represent the current object, and the current object is an object at this time, so we can achieve the desired effect.
In this case
Change outPuter. outer ("123456789") to new outPuter (). outer ("123456789 ")
We will find that there will still be thread security issues. Why? That's because the new OutPuter () is not the same object each time. Therefore, synchronize must be the same object and the same lock.
Now let's add an output3 method.
[Java]View plain copy print?
- Public static synchronized void outer3 (String name ){
- For (int I = 0; I <name. length (); I ++ ){
- System. out. print (name. charAt (I ));
- }
- System. out. println ();
- Span style = "font-size: 14px;" >}</span>
Note that the output3 method is static, so we need to change the OutPuter class to a static class.
Then, change outPuter. outer ("123456789") to outPuter. outer3 ("123456789 ")
The answer is no, because the lock in output3 we use is a class lock, and the lock in output is the current object lock, which is not a lock at all, so what should we do if we want to synchronize output and output3? We can change this in output to OutPuter. class to implement synchronization. At this time, the locks of both methods are class locks, that is, the same lock.
The thread is still learning, and learning is painful, but I hope I can really stick to one thing!