同期されたキーワードは、この方法がロックされていることを表します。これは、この方法を実行するときに、どのスレッド(スレッドAなど)に関係なく、他のスレッドB(またはC、Dなど)がこのメソッド(またはこのクラスの他の同期メソッド)を使用しているかどうかを確認する必要があります。その場合は、この方法を実行する前に、同期された方法を使用してこの方法を実行しているスレッドB(またはc、d)を待ちます。そうでない場合は、発信者をロックして直接実行します。同期されたメソッドと同期ブロックの2つの使用法が含まれます。
マルチスレッドの同期メカニズムはリソースをロックするため、同時に1つのスレッドのみが動作できるようにし、複数のスレッドが同時にアクセスすると発生する可能性のある問題を解決するために同期を使用します。
同期メカニズムは、同期キーワードを使用して実装できます。
同期されたキーワードがメソッドを変更すると、メソッドは同期メソッドと呼ばれます。
同期されたメソッドが実行されるか、例外が発生した場合、ロックは自動的にリリースされます。
以下は、同期されたキーワードの使用を分析する例です。
1.同期されたキーワードの微分使用
例プログラム1
public class threadtest {public static void main(string [] args){example example = new Example();スレッドT1 = new Thread1(例);スレッドT2 = new Thread1(例); t1.start(); t2.start(); }} class example {public synchronized void execute(){for(int i = 0; i <10; ++ i){try {thread.sleep(500); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "hello:" + i); }}} class thread1 extends thread {private example example; public thread1(例の例){this.example = example; } @Override public void run(){embles.execute(); }} execute()メソッドで同期されたキーワードをプレイするかどうかにかかわらず、このサンプルプログラムの実行結果は非常に異なります。
同期されたキーワードが追加されていない場合、2つのスレッドはexecute()メソッドを同時に実行し、出力は2つのグループの同時グループです。
同期されたキーワードが追加された場合、0〜9のセットが最初に出力され、次のセットが出力され、2つのスレッドが順番に実行されることを示します。
2。複数の方法のマルチスレッド状況
プログラムを変更し、別のメソッドexecute2()をサンプルクラスに追加します。
次に、スレッドクラススレッド2を書きます。 thread2のrun()メソッドはexecute2()を実行します。サンプルクラスの両方の方法は、同期されたキーワードによって変更されます。
例プログラム2
public class threadtest {public static void main(string [] args){example example = new Example();スレッドT1 = new Thread1(例);スレッドT2 = new Thread2(例); t1.start(); t2.start(); }} class example {public synchronized void execute(){for(int i = 0; i <20; ++ i){try {thread.sleep((long)math.random() * 1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "hello:" + i); }} public synchronized void execute2(){for(int i = 0; i <20; ++ i){try {thread.sleep((long)math.random() * 1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "world:" + i); }}} class thread1 extends thread {private example example; public thread1(例の例){this.example = example; } @Override public void run(){embles.execute(); }} class thread2拡張スレッド{private Exampleの例; public thread2(例の例){this.example = example; } @Override public void run(){example.execute2(); }}同期されたキーワードが削除された場合、2つの方法は同時に実行され、相互の影響力はありません。
しかし、例の例で書かれているように、2つの方法でさえ:
実行結果は、常に1つのスレッドの出力と、別のスレッドの実行です。
説明:
オブジェクトに複数の同期メソッドがあり、スレッドが特定の瞬間に同期されたメソッドを入力した場合、他のスレッドはメソッドを実行する前にオブジェクトの同期メソッドにアクセスできません。
結論は:
同期されたキーワードがメソッドを変更すると、メソッドは同期メソッドと呼ばれます。
Javaの各オブジェクトには、ロックまたはモニターがあります。スレッドがオブジェクトの同期されたメソッドにアクセスすると、オブジェクトはロックされ、他のスレッドはオブジェクトの同期メソッドにアクセスできません(ここでは、同じ方法だけでなく、すべての同期メソッドを指します)。前のスレッドが実行方法を完了する(または例外をスローする)、オブジェクトのロックがリリースされるまで、他のスレッドがオブジェクトの同期メソッドに再びアクセスできるようにすることではありません。
この時点でオブジェクトがロックされていることに注意してください。別のオブジェクトの場合、オブジェクト間に制限関係はありません。
コード内の2番目のスレッドオブジェクトを作成しようとすると、新しい例オブジェクトが渡されます。その後、2つのスレッドの実行間に制限はありません。
3。静的同期方法を検討してください
同期されたキーワード修正メソッドも静的によって変更されると、非静的同期メソッドがオブジェクトをロックすることが以前に言われていますが、静的メソッドはオブジェクトではなくクラスに属し、このメソッドが配置されているクラスのクラスオブジェクトをロックします。
クラスが生成するオブジェクトの数に関係なく、それらは同じクラスオブジェクトに対応します。
例プログラム3
public class threadtest {public static void main(string [] args){example example = new Example();スレッドT1 = new Thread1(例); //ここで異なるオブジェクトが渡されたとしても、静的メソッドの同期により、複数のスレッドが同時に実行されることはありません。 example = new Example();スレッドT2 = new Thread2(例); t1.start(); t2.start(); }} class example {public synchronized static void execute(){for(int i = 0; i <20; ++ i){try {shood.sleep((long)math.random() * 1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "hello:" + i); }} public synchronized static void execute2(){for(int i = 0; i <20; ++ i){try {thread.sleep((long)math.random() * 1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "world:" + i); }}} class thread1 extends thread {private example example; public thread1(例の例){this.example = example; } @Override public void run(){embles.execute(); }} class thread2拡張スレッド{private Exampleの例; public thread2(例の例){this.example = example; } @Override public void run(){example.execute2(); }}したがって、静的メソッド(execute()とexecute2()の両方が静的キーワードが追加されている場合)である場合、異なるサンプルオブジェクトが2つのスレッドに渡されたとしても、2つのスレッドは互いに制限されています。最初に実行し、次に次に実行する必要があります。
結論は:
同期されたメソッドが静的である場合、スレッドがメソッドにアクセスすると、同期されたメソッドが配置されているオブジェクトではなく、同期されたメソッドが配置されているクラスに対応するクラスオブジェクトをロックします。 Javaでは、クラスにいくつのオブジェクトがある場合でも、これらのオブジェクトは一意のクラスオブジェクトに対応します。したがって、スレッドが同じクラスの2つのオブジェクトの2つの静的および同期メソッドにアクセスすると、実行順序もシーケンシャルになります。つまり、1つのスレッドがメソッドを最初に実行し、もう1つのスレッドは実行が完了した後に開始します。
4。同期ブロック
同期されたブロックライティング方法:
同期(オブジェクト){}これは、スレッドが実行されるとオブジェクトをロックすることを意味します。 (このオブジェクトは、任意のクラスのオブジェクトであるか、このキーワードを使用できます)。
これにより、ロックされたオブジェクトを自分で指定できます。
例プログラム4
public class threadtest {public static void main(string [] args){example example = new Example();スレッドT1 = new Thread1(例);スレッドT2 = new Thread2(例); t1.start(); t2.start(); }} class example {private object object = new object(); public void execute(){synchronized(object){for(int i = 0; i <20; ++ i){try {thread.sleep((long)math.random() * 1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "hello:" + i); }}} public void execute2(){synchronized(object){for(int i = 0; i <20; ++ i){try {thread.sleep((long)math.random() * 1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "world:" + i); }}}}} classスレッド1拡張スレッド{private例の例; public thread1(例の例){this.example = example; } @Override public void run(){embles.execute(); }} class thread2拡張スレッド{private Exampleの例; public thread2(例の例){this.example = example; } @Override public void run(){example.execute2(); }}プログラム4の例で達成される効果は、プログラム2の例と同じです。両方のスレッドは、同時にではなく、順番に実行されます。 1つのスレッドが実行されると、オブジェクトオブジェクトがロックされ、もう1つのスレッドが対応するブロックを実行できません。
同期された方法は、実際には、メソッドのすべてのステートメントを同期したブロックでラッピングし、同期ブロックのブラケットにこのキーワードを渡すことと同等です。もちろん、静的な方法の場合、クラスオブジェクトをロックする必要があります。
おそらく、メソッドのコードの数行のみがスレッドの同期の問題を伴うため、同期されたブロックは、同期されたメソッドよりも詳細に複数のスレッドのアクセスを制御します。同期ブロック内のコンテンツのみが同時に複数のスレッドでアクセスできず、メソッドの他のステートメントは、同時に(同期ブロックの前後を含む)複数のスレッドでアクセスできます。
注:同期によって保護されているデータはプライベートでなければなりません。
結論は:
同期された方法は、粗粒の並行制御です。特定の瞬間に、同期されたメソッドを実行できるスレッドは1つだけです。
同期されたブロックは、ブロック内のコードのみを同期する微調整された並行性制御です。メソッドおよび同期ブロック以外にある他のコードは、複数のスレッドで同時にアクセスできます。