Java multithreaded programming USES Synchronized block synchronization variables

  • 2020-04-01 02:50:00
  • OfStack

The following code demonstrates how to synchronize specific class methods:


package mythread;
public class SyncThread extends Thread
{
 private static String sync = "";
 private String methodType = "";
 private static void method(String s)
 {
  synchronized (sync)
  {
sync = s;
System.out.println(s);
while (true);
  }
 }
 public void method1()
 {
  method("method1");
 }
 public static void staticMethod1()
 {
  method("staticMethod1");
 }
 public void run()
 {
  if (methodType.equals("static"))
staticMethod1();
  else if (methodType.equals("nonstatic"))
method1();
 }
 public SyncThread(String methodType)
 {
  this.methodType = methodType;
 }
 public static void main(String[] args) throws Exception
 {
  SyncThread sample1 = new SyncThread("nonstatic");
  SyncThread sample2 = new SyncThread("static");
  sample1.start();
  sample2.start();
 }
}

The operation results are as follows:


method1
staticMethod1

Many readers may be surprised to see the above results. In the code above, the method1 and staticMethod1 methods use the static string variable sync for synchronization. Only one of the two methods can execute at the same time, and both methods execute an infinite loop of line 014. Therefore, the output should be either method1 or staticMethod1. But the program outputs both strings.
The answer to that is easy, let's just look at line 012. Previously, the value of sync was changed in this line. Let's talk about the String type in Java. The String type is different from other complex types in Java. When using a String variable, Java creates a new instance of the String type simply by assigning a value to the variable once. The following code is shown:


String s = "hello";
System.out.println(s.hashCode());
s = "world";
System.out.println(s.hashCode()); 

In the code above. The value of the hashCode of the first s is not the same as the value of the hashCode of the second s. Since you do not need to use new to create an instance of the String class, be careful not to assign a value to a variable of type String when synchronizing it, otherwise the variable will be out of sync.
Since a new instance of sync has been created on line 012, assuming that method1 executes first, when the method1 method executes line 013, the value of sync is no longer the original value, and the method1 method locks the original value of the sync variable. At this point, staticMethod1 executes exactly to synchronized(sync), and the sync to be locked in the staticMethod1 method and the sync to be locked in the method1 method are not the same, so the synchronization of the two methods has been broken.
The solution, of course, is to remove line 012. This line was added in this example only to illustrate that changing the value of a synchronized variable in a synchronized block can break synchronization between methods when using class variables to synchronize methods. To avoid this completely, you can use the final keyword when defining synchronization variables. If the above program line 005 can be changed to the following form:


private final static String sync = "";

With the final keyword, sync can only assign values to it at definition time and cannot be modified later. If you assign a value to sync elsewhere in the program, the program won't compile. In development tools such as Eclipse, you will be prompted directly in the wrong place.
Synchronized blocks can be understood from two perspectives. If understood from the point of view of class methods, you can synchronize the corresponding methods through class variables. If understood in terms of class variables, you can use synchronized blocks to ensure that a class variable is accessed by only one method at a time. No matter from which point of view they are understood, the essence is the same, that is, the use of class variables to acquire the synchronization lock, through the mutual exclusion of the synchronization lock to achieve the synchronization.
Note: when using synchronized blocks, it should be noted that a synchronized block can only use an object as its parameter. Synchronized is not available for variables of a simple type (such as int, char, Boolean, etc.).


Related articles: