Home  >  Article  >  Java  >  Detailed introduction to the use of Java synchronized block

Detailed introduction to the use of Java synchronized block

黄舟
黄舟Original
2017-03-24 10:58:231574browse

Java synchronized block (synchronized block) is used to mark methods or code blocks as synchronized. Java synchronized blocks are used to avoid races. This article introduces the following content:

  • Java synchronization keyword (synchronzied)

  • Instance method synchronization

  • Static method synchronization

  • Synchronization block in instance method

  • Synchronization block in static method

  • Java synchronization example

Java synchronization keyword (synchronized)

Synchronized blocks in Java are marked with synchronized. A synchronized block in Java is synchronized on a object. All synchronized blocks synchronized on an object can only be entered and performed by one thread at the same time. All other threads waiting to enter this synchronized block will be blocked until the thread executing this synchronized block exits.

There are four different synchronization blocks:

  1. Instance methods

  2. Static methods

  3. Synchronized blocks in instance methods

  4. Synchronized blocks in static methods

The above synchronized blocks are all synchronized on different objects. Which synchronization block is actually needed depends on the situation.

Instance method synchronization

The following is a synchronized instance method:

public synchronized void add(int value){
this.count += value;
 }

Note the synchronized keyword in the method declaration. This tells Java that the method is synchronous.

Java instance method synchronization is synchronized on the object that owns the method. In this way, the method synchronization of each instance is synchronized on a different object, that is, the instance to which the method belongs. Only one thread can run within an instance method synchronized block. If multiple instances exist, a thread can perform operations in one instance synchronized block at a time. One thread per instance.

Static method synchronization

Static method synchronization is the same as the instance method synchronization method, and also uses the synchronized keyword. Java static method synchronization is as follows:

public static synchronized void add(int value){
 count += value;
 }

Similarly, the synchronized keyword here tells Java that this method is synchronized.

The synchronization of static methods refers to synchronization on the class object where the method is located. Because a class can only correspond to one class object in the Java virtual machine, only one thread is allowed to execute static synchronization methods in the same class at the same time.

For static synchronized methods in different classes, one thread can execute the static synchronized methods in each class without waiting. Regardless of which static synchronization method in the class is called, a class can only be executed by one thread at the same time.

Synchronized blocks in instance methods

Sometimes you don’t need to synchronize the entire method, but a part of the method. Java can synchronize part of a method.

An example of a synchronized block in an asynchronous Java method is as follows:

public void add(int value){

    synchronized(this){
       this.count += value;
    }
  }

The example uses the Java synchronized block constructor to mark a piece of code as synchronized. This code executes like a synchronous method.

Note that the Java synchronized block constructor encloses the object in parentheses. In the above example, "this" is used, which is the instance itself that calls the add method. The object enclosed in parentheses in the synchronized constructor is called a monitor object. The above code uses monitor object synchronization, and the synchronized instance method uses the instance of the calling method itself as the monitor object.

Only one thread can execute within a Java method synchronized to the same monitor object at a time.

The following two examples synchronize the instance objects they are called, so they are equivalent in synchronization execution effects.

public class MyClass {

   public synchronized void log1(String msg1, String msg2){
      log.writeln(msg1);
      log.writeln(msg2);
   }

   public void log2(String msg1, String msg2){
      synchronized(this){
         log.writeln(msg1);
         log.writeln(msg2);
      }
   }
 }

In the above example, only one thread can execute in either method of the two synchronized blocks at a time.

If the second synchronization block is not synchronized on this instance object, then the two methods can be executed by the thread at the same time.

Synchronization blocks in static methods

Similar to the above, the following is an example of synchronization of two static methods. These methods are synchronized on the class object to which the method belongs.

public class MyClass {
    public static synchronized void log1(String msg1, String msg2){
       log.writeln(msg1);
       log.writeln(msg2);
    }

    public static void log2(String msg1, String msg2){
       synchronized(MyClass.class){
          log.writeln(msg1);
          log.writeln(msg2);
       }
    }
  }

These two methods are not allowed to be accessed by threads at the same time.

If the second synchronization block is not synchronized on the MyClass.class object. Then these two methods can be accessed by threads at the same time.

Java Synchronization Example

In the following example, two threads are started, both calling the add method of the same instance of the Counter class. Because the synchronization is on the instance to which the method belongs, only one thread can access this method at the same time.

public class Counter{
     long count = 0;

     public synchronized void add(long value){
       this.count += value;
     }
  }
  public class CounterThread extends Thread{

     protected Counter counter = null;

     public CounterThread(Counter counter){
        this.counter = counter;
     }

     public void run() {
    for(int i=0; i<10; i++){
           counter.add(i);
        }
     }
  }
  public class Example {

    public static void main(String[] args){
      Counter counter = new Counter();
      Thread  threadA = new CounterThread(counter);
      Thread  threadB = new CounterThread(counter);

      threadA.start();
      threadB.start();
    }
  }

创建了两个线程。他们的构造器引用同一个Counter实例。Counter.add方法是同步在实例上,是因为add方法是实例方法并且被标记上synchronized关键字。因此每次只允许一个线程调用该方法。另外一个线程必须要等到第一个线程退出add()方法时,才能继续执行方法。

如果两个线程引用了两个不同的Counter实例,那么他们可以同时调用add()方法。这些方法调用了不同的对象,因此这些方法也就同步在不同的对象上。这些方法调用将不会被阻塞。如下面这个例子所示:

public class Example {

   public static void main(String[] args){
     Counter counterA = new Counter();
     Counter counterB = new Counter();
     Thread  threadA = new CounterThread(counterA);
     Thread  threadB = new CounterThread(counterB);

     threadA.start();
     threadB.start();
   }
 }

注意这两个线程,threadA和threadB,不再引用同一个counter实例。CounterA和counterB的add方法同步在他们所属的对象上。调用counterA的add方法将不会阻塞调用counterB的add方法。

The above is the detailed content of Detailed introduction to the use of Java synchronized block. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn