ホームページ >Java >&#&チュートリアル >Javaでの同期関数の共有例

Javaでの同期関数の共有例

黄舟
黄舟オリジナル
2017-09-19 10:09:101343ブラウズ

この記事では、Java の同期関数の詳細な説明に関する関連情報を中心に紹介します。この記事が、同期関数の使用方法を理解するのに役立つことを願っています。

同期の詳細な説明。 Java の関数

Java のクラスのメンバー関数が synchronized で変更された場合、それは同じオブジェクトに対応します。複数のスレッドがこのオブジェクトの同期関数を呼び出すときは、前のスレッドが呼び出しを完了するまで待たなければなりません。次のスレッドから呼び出すことができます。

それでは、コードに示されているように、クラスに synchronized によって変更される 2 つのメンバー関数がある場合、2 つのスレッドが実行されているときに、同じオブジェクトに対して、1 つは funcA を呼び出し、もう 1 つは funcB を呼び出すことができますか?

Mysyn はそのようなクラスです。2 つのスレッドがある場合、1 つは run メソッドで最初に funcA を実行し、次に funcB を実行し、もう 1 つのスレッドは run メソッドで最初に funcB を実行し、次に funcA を実行します。開始A...を出力するときに、開始B...を直接出力することは可能ですか?


public class MySyn { 
  public synchronized void funcA(String str){ 
    System.out.println(str+":"); 
    System.out.println("start A..."); 
    try { 
      Thread.sleep(5000); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
    System.out.println("...A end"); 
  } 
   
  public synchronized void funcB(String str){ 
    System.out.println(str+":"); 
    System.out.println("start B..."); 
    try { 
      Thread.sleep(5000); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
    System.out.println("...B end"); 
  } 
}

テストコードは次のとおりです:

このスレッドは最初に funcA を実行します


public class Mythread implements Runnable { 
 
  private MySyn mysyn; 
  private String id; 
  public Mythread(MySyn syn, String id){ 
    this.mysyn = syn; 
    this.id = id; 
  } 
  @Override 
  public void run() { 
     
    this.mysyn.funcA(id); 
    try { 
      Thread.sleep(1000); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
    this.mysyn.funcB(id); 
  } 
   
  public static void main(String arg[]){ 
    MySyn syn=new MySyn(); 
    Thread t1 = new Thread(new Mythread(syn, "t1")); 
    Thread t2 = new Thread(new YourThread(syn, "t2")); 
     
     
    t1.start(); 
    t2.start(); 
  } 
}

このスレッドは最初に funcB を実行します


public class YourThread implements Runnable { 
 
  private MySyn mysyn; 
  private String id; 
  public YourThread(MySyn syn, String id){ 
    this.mysyn = syn; 
    this.id=id; 
  } 
  @Override 
  public void run() { 
    this.mysyn.funcB(id); 
    this.mysyn.funcA(id); 
     
 
  } 
 
}

出力結果は主に次のとおりです:そうだね

if Mythread の run メソッドで 2 つの関数呼び出しの間のスリープをキャンセルすると、結果はおそらく次のようになります:


t1: 
start A... 
...A end 
t2: 
start B... 
...B end 
t2: 
start A... 
...A end 
t1: 
start B... 
...B end

スレッドのスケジュールにより個々の結果は異なる可能性がありますが、決して次のような結果にはなりません: start A..​​. Following start B を直接実行すると ..


それでは、funcB が同期関数ではない場合、上記のコードを実行するとどうなるでしょうか?

funcB の synchronized キーワードを削除するためにコードが少し変更されています。実行結果は次のとおりです:

t1: 
start A... 
...A end 
t1: 
start B... 
...B end 
t2: 
start B... 
...B end 
t2: 
start A... 
...A end

明らかに、開始 A... の結果は開始 B.... の後に直接出力されます。


同様に、Mysyn クラスにパブリック メンバー変数がある場合、マルチスレッドは、同期関数の呼び出し中に別のスレッドによってメンバー変数を変更することもできます。

上記の実験は、同期されたメンバー関数は、同じオブジェクトの同期された関数呼び出し内の他の同期された関数 (それ自体を含む) に対してのみ排他的な影響を与えることができることを示しています。つまり、マルチスレッド操作では、同じオブジェクトは現時点では次のことしかできません。同期された関数は実行されていますが、他の非同期関数の実行やメンバーへのアクセスは除外されません。

さて、クラスに 2 つの静的同期メソッドがあると仮定します。状況はどうでしょうか?

結果は似ているため、特定の実装については繰り返しません:

マルチスレッドでは、現在、同じクラスで実行できるクラス同期関数 (静的同期関数) は 1 つだけですが、他の非同期静的関数は実行できます。静的メンバーの実行またはアクセスは除外されません

以上がJavaでの同期関数の共有例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。