Java マルチスレッド プログラミングの Synchronized キーワードの詳細な説明

高洛峰
リリース: 2017-01-05 14:43:38
オリジナル
1495 人が閲覧しました

この記事では、JAVA マルチスレッドのオブジェクト ロックとしての synchronized キーワードに関するいくつかの知識ポイントを紹介します。

いわゆるオブジェクトロックとは、オブジェクトを同期的にロックすることを意味します。オブジェクトのロックについては、こちらの記事を参照してください。

1. 分析

synchronized は、次の形式でインスタンス メソッドを変更できます:

public class MyObject {
  synchronized public void methodA() {
    //do something....
  }
ログイン後にコピー

ここで、synchronized キーワードは現在のオブジェクトをロックします。これがオブジェクト ロックと呼ばれる理由でもあります。

現在のオブジェクトをロックする理由は何ですか? MethodA() はインスタンス メソッドであるため、methodA() を実行する場合は、object.method() (obj.methodA() の形式で呼び出す必要があります。obj は MyObject クラスのオブジェクトです。同期ロックオブジェクトobj)。

上記のコードは次のように書くこともできます:

public class MyObject {
 
  public void methodA() {
    synchronized(this){
      //do something....
    }
  }
ログイン後にコピー

2. 特徴

synchronized キーワードを使用して同期することの明らかな特徴は次のとおりです: MyObject クラスで複数の同期された変更インスタンス メソッドが定義されている場合、マルチスレッド 同じ MyObject クラスのオブジェクトの場合、これらのメソッドは同期的にのみ実行できます。つまり、同期変更メソッドを実行した後、別の同期変更メソッドを実行できます。

次のように:

public class MyObject {
 
  synchronized public void methodA() {
    //do something....
  }
 
  synchronized public void methodB() {
    //do some other thing
  }
}
ログイン後にコピー

MyObject クラスには 2 つの同期された変更メソッドがあります。

public class ThreadA extends Thread {
 
  private MyObject object;
//省略构造方法
  @Override
  public void run() {
    super.run();
    object.methodA();
  }
}
ログイン後にコピー

スレッドAはmethodA()を実行します

public class ThreadB extends Thread {
 
  private MyObject object;
//省略构造方法
  @Override
  public void run() {
    super.run();
    object.methodB();
  }
}
ログイン後にコピー

スレッドBはmethodB()を実行します

public class Run {
  public static void main(String[] args) {
    MyObject object = new MyObject();
 
    //线程A与线程B 持有的是同一个对象:object
    ThreadA a = new ThreadA(object);
    ThreadB b = new ThreadB(object);
    a.start();
    b.start();
  }
}
ログイン後にコピー

スレッドAとスレッドBはMyObjectクラスの同じオブジェクトを保持していますが、この2つはたとえば、スレッド B は、メソッド B() メソッドを実行する前に、スレッド A がメソッド A() メソッドの実行を完了するまで待機する必要があります。

3. 結論

上記からわかるように、この記事で説明する同期ロックの範囲はオブジェクト全体です。クラス内に同期された変更された同期メソッドが複数あり、複数のスレッドがクラスの同じオブジェクト (クラスの同じオブジェクト) を保持している場合、それらが異なるメソッドを呼び出している場合でも、各メソッドの実行も同期されます。

同期されたメソッド間に共有変数がない場合、またはメソッド間に接続がないが同期的にのみ実行できる場合、効率に影響します。

4. アプリケーション - データの不整合によるダーティデータの読み取りを避けるために同期を使用します。

次の例:

public class MyObject {
 
  private String userName = "b";
  private String passWord = "bb";
   
  synchronized public void methodA(String userName, String passWord) {
    this.userName = userName;
    try{
      Thread.sleep(5000);
    }catch(InterruptedException e){
       
    }
    this.passWord = passWord;
  }
 
  synchronized public void methodB() {
    System.out.println("userName" + userName + ": " + "passWord" + passWord);
  }
}
ログイン後にコピー

methodA() はユーザー名とパスワードを変更します。実際には、ユーザー名はパスワードに対応します。

methodB() はユーザー名とパスワードを読み取る役割を果たします。

methodB()がsynchronizedで変更されていない場合、スレッドAはmethodA()を呼び出して7行目まで実行し、ユーザー名を変更し、何らかの理由(9行目でスリープしているなど)でCPUを放棄します。

この時、スレッドBがmethodB()を実行すると、読み込まれるユーザー名はスレッドAが変更したユーザー名("a")となりますが、パスワードは元のパスワード("bb")となります。スレッド A がスリープ状態になり、パスワードを変更する時間がなかったためです。

ただし、me​​thodB() が synchronized で変更された場合、スレッド B は、メソッド B を実行してユーザー名とパスワードを読み取る前に、スレッド A の実行が完了する (つまり、ユーザー名とパスワードが変更される) まで待機することしかできません。したがって、データの不整合によって引き起こされるダーティ リードの問題が回避されます。

以上がこの記事の全内容です。Java プログラミングを学習する皆さんのお役に立てれば幸いです。

Java マルチスレッド プログラミングの Synchronized キーワードの詳細な説明と関連記事については、PHP 中国語 Web サイトに注目してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート