Heim  >  Artikel  >  Java  >  Detaillierte Beispielcode-Einführung in den Java-Synchronisationscodeblock

Detaillierte Beispielcode-Einführung in den Java-Synchronisationscodeblock

黄舟
黄舟Original
2017-02-28 10:47:182258Durchsuche

Ein synchronisierter Java-Block synchronisiert eine Methode oder einen Codeblock. Java-synchronisierte Blöcke können verwendet werden, um statische Bedingungen zu vermeiden. Synchronisierte Blöcke in Java werden durch die Verwendung des synchronisierten Schlüsselworts gekennzeichnet. Ein synchronisierter Block in Java ist für einige Objekte synchronisiert. Alle synchronisierten Blöcke, die auf allen Objekten synchronisiert sind, können nur von einem Thread gleichzeitig ausgeführt werden. Alle anderen Threads, die versuchen, in den synchronisierten Block einzutreten, werden blockiert, bis der Thread innerhalb des synchronisierten Blocks den Block verlässt.

Das synchronisierte Schlüsselwort kann verwendet werden, um vier verschiedene Arten von Blöcken zu markieren:

Instanzmethode


Statische Methode

  1. Codeblock in Instanzmethode

  2. Codeblock in statischer Methode

  3. Diese Blöcke werden in verschiedenen Objekten synchronisiert. Welchen Synchronisierungsblocktyp Sie benötigen, hängt vom jeweiligen Szenario ab.

  4. Synchronisierte Instanzmethoden

Hier ist ein Beispiel:

Beachten Sie das synchronisierte Schlüsselwort in der Methodenlebensdauer von verwenden. Dadurch wird Java mitgeteilt, dass diese Methode synchronisiert ist. Eine synchronisierte Instanzmethode in Java wird auf dem zu dieser Methode gehörenden Instanzobjekt synchronisiert. Daher wird die Synchronisierungsmethode jeder Instanz auf ein anderes Objekt synchronisiert: ihre eigene Instanz. Nur ein Thread kann eine instanzsynchronisierte Methode ausführen, und dann kann ein Thread jeweils eine synchronisierte Instanzmethode ausführen. Ein Thread pro Instanz.

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

Statische Methoden werden genau wie Instanzmethoden mit dem Schlüsselwort synchronisiert als synchronisiert markiert. Hier ist ein Beispiel:

Hier gibt es auch ein synchronisiertes Schlüsselwort, um Java mitzuteilen, dass diese Methode synchronisiert ist. Synchronisierte statische Methoden werden auf dem Klassenobjekt der Klasse synchronisiert, zu der die statische Methode gehört. Da für jede Klasse in der Java Virtual Machine nur ein Klassenobjekt vorhanden ist, kann nur ein Thread eine synchronisierte statische Methode derselben Klasse ausführen.

Wenn sich diese statische synchronisierte Methode in verschiedenen Klassen befindet, kann ein Thread die interne statische synchronisierte Methode jeder Klasse ausführen. Threads jeder Klasse, unabhängig davon, welche statische Synchronisationsmethode sie aufrufen.

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

Synchronisierte Blöcke in Instanzmethoden

Sie können nicht die gesamte Methode synchronisieren. Manchmal ist es besser, Teile einer Methode zu synchronisieren. Java-synchronisierte Blöcke innerhalb von Methoden machen dies möglich.

Hier ist ein Beispiel:

In diesem Beispiel werden Java-Synchronisationsblöcke verwendet, um einen synchronisierten Codeblock zu erstellen. Wenn es sich um eine synchrone Methode handelt, wird diese Methode ausgeführt.

Beachten Sie, wie dieser Java-Synchronisationsblock aus Teilen eines Objekts aufgebaut ist. In diesem Beispiel wird „this“ verwendet, also die Instanz der aufgerufenen Add-Methode. Das durch die Synchronisierung erstellte Objekt in den akzeptierenden Klammern wird als Monitorobjekt bezeichnet. Dieser Code geht davon aus, dass das Monitorobjekt synchron ist. Eine synchronisierte Instanzmethode verwendet das Objekt, zu dem sie gehört, als Überwachungsobjekt.

In einem mit Java synchronisierten Block desselben überwachten Objekts kann nur ein Thread ausgeführt werden.

Die folgenden zwei Instanzen werden auf der Instanz synchronisiert, die sie aufgerufen haben. Daher sind sie äquivalent:
  public void add(int value){

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

In diesem Beispiel kann also nur ein Thread einen der beiden synchronisierten Blöcke ausführen.

Hierfür gibt es einen zweiten Synchronisationsblock, der auf ein anderes Objekt synchronisiert wird, und dann kann ein Thread jeweils nur eine interne Methode ausführen.


  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);
       }
    }
  }
Synchronisierter Block in statischer Methode


Hier sind zwei identische Instanzen als statische Methode. Diese Methoden werden im Klassenobjekt der Klasse synchronisiert, zu der diese Methode gehört:

Nur ​​ein Thread kann beide Methoden gleichzeitig ausführen. Es gibt einen zweiten Synchronisationsblock, der auf ein anderes Objekt synchronisiert wird, für MyClass.class, und dann kann ein Thread nur eine interne Methode gleichzeitig ausführen.

  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);  
       }
    }
  }
Java-Synchronisationsinstanz


Hier ist eine Instanz, die zwei Threads startet und beide die Add-Methode derselben Instanz von Counter aufrufen. Es kann jeweils nur ein Thread die Add-Methode derselben Instanz aufrufen, da diese Methode mit der Instanz synchronisiert ist, zu der sie gehört:

  public class Counter{
     
     long count = 0;
    
     public synchronized void add(long value){
       this.count += value;
     }
  }


Zwei Threads werden erstellt. Zwei identische Counter-Instanzen werden an ihre Konstruktoren übergeben. Die Add-Methode wird auf der Instanz synchronisiert, da die Add-Methode eine Instanzmethode ist und als synchronisiert markiert ist. Daher kann jeweils nur ein Thread diese Add-Methode aufrufen. Andere Threads warten, bis der erste Thread die Add-Methode verlässt, bevor sie ausgeführt werden können.

  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);
        }
     }
  }
Wenn zwei Threads auf zwei separate Counter-Instanzen verweisen, ist der gleichzeitige Aufruf der Add-Methode kein Problem. Dieser Aufruf erfolgt für ein anderes Objekt, daher wird dieser Methodenaufruf auch für ein anderes Objekt synchronisiert (das Objekt, das zu dieser Methode gehört). Daher wird dieser Anruf nicht blockiert. Hier ist ein Beispiel:

  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(); 
    }
  }

注意这两个线程,他们不再引用相同的实例。counterA和counterB的add方法同步在它们自己的实例上。因此不会堵塞。

Java并发工具

这个synchronized机制是java的第一个途径对于访问同步访问被多线程共享的对象。但是这个synchronized机制不是最高级的。那就是为什么Java 5提供了一个并发工具类的集合去帮助开发者实现更细粒度的并发控制相对于synchronized而言。


 以上就是Java同步代码块的详细实例代码介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn