Multithreaded learning - basics (9) Thread synchronization Synchronized keyword

1. Thread synchronization
1. There are two scopes of the synchronized keyword:
(1) In an object instance: synchronized aMethod(){} can prevent multiple threads from accessing the synchronized method of this object at the same time (if an object has multiple synchronized method, as long as one thread accesses one of the synchronized methods, other threads cannot access any synchronized method of this object at the same time). At this time, the synchronized methods of different object instances do not interfere with each other. That is to say: other threads can still access synchronized methods in different instances of the same class.
(2) is the scope of a class: synchronized static aStaticMethod{} prevents multiple threads from accessing synchronized static methods in this class at the same time. It works on all object instances of the class.

2. In addition to using the synchronized keyword before the method, it can also be used in a block in the method, indicating that the resources of this block are mutually exclusive access, the usage is:
synchronized(this){/code block/}
Its The scope is the current object.
3. The synchronized keyword cannot be inherited, that is to say, the synchronized fun() in the base class is not automatically synchronized fun() in the inherited class, but becomes fun(), and inheritance requires you to display it. Designate one of its methods as a synchronized method.


In general, the synchronized keyword can be used as a modifier of a function, or as a statement within a function, which is usually called a synchronization method and a synchronized statement block. If more detailed classification, the synchronized keyword can be used for instance variables, object reference (object reference), static functions and class literals (class name literal constants).

Before further elaboration, we need to clarify the following points:
A: No matter the synchronized keyword is added to a method or an object, the lock it acquires is an object, not a piece of code or function as a lock, and the synchronized method may also be used by other threads. (Note: the objects of other threads refer to: the same class as the current object but not the same instance).
B: Each object has only one lock associated with it.
C: Implementing synchronization requires a lot of system overhead as a price, and may even cause deadlock, so code synchronization control that doesn't matter as much as possible.

Next, analyze the impact of the synchronized keyword used in different places and team code:
Assume: P1, P2 are different objects of the same class, this class defines the synchronization block or synchronization method in the following situations, P1, P2 can call them.
1. When using the synchronized keyword as a function modifier, the code is as follows:

1 public synchronized void method_A(){
2     //......
3 }

   This is the synchronization method. At this time, which object is synchronized locked? It locks the object on which the synchronized method is called. That is to say, when an object P1 executes this synchronization method in different threads, they will be mutually exclusive to achieve the effect of synchronization. However, other instance objects of the class to which this object belongs, such as P2, can call the synchronized method modified by synchronized at will. The root cause:
When the synchronized keyword modifies a method, this method is called a synchronized method. The object locked by the synchronized method is the instantiated object of the class where the synchronized method is located, but there can be an infinite number of class instantiations, so in the end it is locked Which is it? The answer is the object that is currently calling the synchronized decorated method.
Since each object will be assigned a lock by the JVM, a class has multiple instantiated objects, and the same object can be called by multiple threads. What is being locked is "all the synchronized methods or synchronized blocks of the current object of the current thread team. access rights". Once a thread is in use, other threads can only be queued and cannot be used.
The sample code above is equivalent to the following code:

1 public void method_A()
2 {
3      synchronized (this) // synchronized同步块
4      {
5            //…..
6      }
7 }

 


Analyze the above code: In the
synchronized code block: what does this refer to? It refers to the object on which this method is called, such as P1. It can be seen that the essence of the synchronization method is to apply synchronized to the object reference. ——The thread that has obtained the P1 object lock can call the synchronization method of P1, but for P2, the P1 lock has nothing to do with it, and the program may also get rid of the control of the synchronization mechanism in this case, causing data confusion:

2. Synchronous code block, the example code is as follows:

1  public  void method3(SomeObject so) {
 2    synchronized (so)
 3    {
 4      // ..... synchronized block 
5    }
 6 }

 

 

         At this time, the lock is the so object, and whoever gets the lock can run the code it controls. When there is a clear object as a lock, you can write a program like this, but when there is no clear object as a lock, and you just want to synchronize a piece of code, you can create a special instance variable (it has to be an object) to act as a lock :

1 class Foo implements Runnable
2 {
3     private byte[] lock = new byte[0]; // 特殊的instance变量
4     public void methodA()
5     {
6                 synchronized(lock) { //… }
7     }
8      //…..
9 }

 


Note: A zero-length byte array object will be more economical to create than any object - look at the compiled bytecode: it only takes 3 opcodes to generate a zero-length byte[] object, while Object lock = new Object() 7 lines of opcodes are required.
3. Apply synchronized to static functions. The sample code is as follows:

1  Class Foo
 2  {
 3    public  synchronized  static  void methodAAA() // synchronized static function 
4    {
 5    // …. 
6    }
 7    public  void methodBBB()
 8    {
 9      synchronized (Foo. class ) // class literal(class name literal constant) 
10    }
 11 }

 


The methodBBB() method in the code is the case where the class literal is used as a lock. It has the same effect as the synchronized static function. The lock obtained is very special. It is the class to which the object currently calling this method belongs (Class, not Then a specific object generated by this Class).
It can be inferred: if a synchronized static function A is defined in a class, and a synchronized instance function B is also defined, then the same object Obj of this class accesses the two methods of A and B respectively in multiple threads. Synchronized because their locks are not the same. The lock of method B is the object Obj, and the lock of method A is the Class to which Obj belongs.
To sum up:
1. The purpose of thread synchronization is to protect the destruction of resources when multiple threads access a resource.
2. The thread synchronization method is implemented through locks. Each object has only one lock. This lock is associated with a specific object. Once a thread acquires the object lock, other threads accessing the object can no longer access the object. other asynchronous methods.
3. For static synchronization methods, the lock is for this class, and the lock object is the Class object of the class. Locks for static and non-static methods do not interfere with each other. A thread acquires a lock, and when accessing a synchronized method on another object in a synchronized method, it acquires both object locks.
4. For synchronization, it is the key to keep awake on which object to synchronize.
5. When writing thread-safe classes, you need to always pay attention to making correct judgments on the logic and security of multiple threads competing to access resources, analyze "atomic" operations, and ensure that other threads cannot access competing resources during atomic operations.
6. When multiple threads wait for an object lock, the thread that does not acquire the lock will block.
7. Deadlock is caused by threads waiting for each other for locks, and the probability of occurrence in practice is very small. Really let you write a deadlock program, not necessarily easy to use, huh, huh. However, once the program deadlocks, the program will die.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324750060&siteId=291194637