This is the third day of my participation in the August More Text Challenge

The synchronized keyword

preface

  • Java Synchronized provides a mechanism for accessing objects with multiple threads simultaneously. Before java8, the locking method was heavy, but since then, there has been a lightweight update to keyword locking.

The synchronized keyword

  • Java synchronization block usedsynchronizedKeyword tags that cause code in a synchronized code block to execute only within one thread, blocking other threads that enter that code block.
  • Tag type:
    • Instance method: The object that acts on the calling method
    • Static methods: Apply to all objects
    • Code block within instance method: the object that acts on the calling method
    • Code blocks within static methods: apply to all objects

Synchronous instance method

  • The same class can have more than one instance object, while the synchronized instance method means that only one thread of the same instance in different threads can access the method in the synchronized code block of the same instance, and the different instances do not affect each other.
public class myclass{ private int a = 0; public synchronized void add(int value){ this.a += value; } public synchronizrd void subtract(int value){ this.a -= value; }}Copy the code

Synchronous static method

  • Synchronized static methods are synchronized on the class of the static method, so different threads access the same part of the code block, and only one thread can execute the methods in a synchronized static code block at a time.
public class myclass{ private static int a = 0; public static synchronized void add(int value){ this.a += value; } public static synchronizrd void subtract(int value){ this.a -= value; }}Copy the code

Synchronize a block of code within an instance method

  • Sometimes you don’t need to synchronize the entire method, only a portion of the code block. Used in the codethisKeyword, which is the instance calling the Add method, which is the current instance object. Therefore, the different instance objects do not interact with each other, while the synchronized instance method is consistent, and the same instance object can only be accessed by the same thread at the same time.
private int a = 0; public void add(int value){ synchronized(this){ this.a += value; }}Copy the code

Synchronize code blocks within static methods

  • Unlike block synchronization within instance methods, blocks within static methods need to lock the class itself. This is equivalent to locking static methods, which can only be accessed by the same thread at a time, regardless of the instance object itself.
public class myclass{ private static int a = 0; public static void add(int value){ synchronized(myclass.class){ this.a += value; } } public static void subtract(int value){ synchronized(myclass.class){ this.a -= value; }}}Copy the code

Synchronization in lambda expressions

  • In the same way,synchronizedIt can be used in lambda expressions with the same locking logic as normal, as in the following example for synchronizing class objects.
Consumer<String> func = (String param) -> { synchronized(SynchronizedExample.class) { System.out.println( Thread.currentThread().getName() + " step 1: " + param); try { Thread.sleep( (long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println( Thread.currentThread().getName() + " step 2: " + param); }};Copy the code

Synchronization and data visibility

  • If not usedsynchronizedKeyword, cannot get the value of a shared variable modified in another thread. At the same time, there is no guarantee that data variables held in CPU registers in one thread will be committed to the main, nor that variables in other threads will be flushed from the main memory. While the use ofsynchronizedWhen a thread enters the synchronized block, it will flush all the shared variable values from main memory. When it leaves the synchronized block, it will write the shared variable values in the CPU register back to main memory.

Synchronization and instruction reordering

  • To solve the problem of writes inside the synchronized block being reordered to be executed outside the synchronized block,synchronizedRestrictions on reordering before, after, and in synchronized code blocks are set to ensure that instruction reordering exceptions do not occur.

The object to synchronize

  • In fact, you can choose any object for synchronization, but don’t choose String or any wrapper class of primitive type for synchronization. The compiler may optimize these objects, and reuse may occur in different places where it is assumed that the same instance is being used.

Synchronize code performance overhead

  • Entering or exiting a synchronized block in Java incurs a small performance overhead, which you should pay attention to if you enter it multiple times frequently. Try not to use a synchronization lock that is coarser than necessary and refine the synchronization lock. And with the Java version,synchronizedHas been converted from heavy lock to gradient lock, not heavy lock when competition is low.

Afterword.

  • How many events through the ages? Leisurely. The Yangtze River is still rolling.