この記事では主にJava同期ロック(同期)の詳しい説明と例を紹介しますので、必要な方は参考にしてください
Java同期ロック(同期)の詳細な説明と例
各スレッドに割り当てられるCPU。 Java ではタイムスライスはランダムであり、Java の多くのスレッドは同じリソースを共有します。たとえば、電車の切符を販売する場合、電車の切符は確実ですが、電車の切符を販売するウィンドウはどこにでもあり、各ウィンドウは 1 つのスレッドに相当するため、複数のスレッドが存在します。すべての鉄道チケットのリソースを共有します。ある時点で 2 つのスレッドが同時にこのリソースを使用すると、取り出す乗車券が同じ (同じ座席番号) になり、乗客に迷惑がかかります。たとえば、次のプログラム:
package com.pakage.ThreadAndRunnable; public class Runnable_demo implements Runnable{ private int ticket=10; public Runnable_demo(){ } @Override public void run() { for(int i=0;i<20;i++){ if(this.ticket>0){ //休眠1s秒中,为了使效果更明显,否则可能出不了效果 try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); } } } public static void main(String args[]){ Runnable_demo demo=new Runnable_demo(); //基于火车票创建三个窗口 new Thread(demo,"a").start(); new Thread(demo,"b").start(); new Thread(demo,"c").start(); } }
プログラムの実行結果:
ウィンドウ C と B は両方とも 10 番のチケットを販売し、ウィンドウ A と B はそれぞれ 0 番のチケットを販売し、-チケット No. を販売したことがわかります。 1.この状況が発生する理由は 1. c スレッドと b スレッドのチケットが 10 である場合、c スレッドが 10 番のチケットを取り出した後、チケットはまだ来ていないため 1 減らされ、b スレッドはチケットを取得します。 ; 2. ticket=1 の場合、スレッド c はチケット番号 1 を取り出します。チケットが来る前に、チケットは 1 減らされます。スレッド a と b は if に入ります。 判定文を次々と出していくと、チケットが1減り、スレッドbがチケットを拾ったとき、0番と-1番のチケットを取得しました。
上記の状況を変えるにはどうすればよいでしょうか? スレッドが電車のチケットのリソースを使用したいとき、スレッドにロックを与え、そのスレッドが完了するのを待ってから別のスレッドにロックを渡します。このリソースを使用するには。そうすれば、上記のような事態は起こらなくなります。 このロック機能を実装するには、synchronized キーワードを使用する必要があります。
synchronized キーワードには 2 つの用途があります1. メソッド名の前に配置して同期メソッドを形成します。2. ブロックの前に配置して同期ブロックを形成します。
1. 同期メソッドを使用して上記の例を次のように変更します:
package com.pakage.ThreadAndRunnable; public class Runnable_demo implements Runnable{ private int ticket=10; public Runnable_demo(){ } @Override public void run() { for(int i=0;i<20;i++){ if(this.ticket>0){ //休眠1s秒中,为了使效果更明显,否则可能出不了效果 try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } this.sale(); } } } public synchronized void sale(){ if(this.ticket>0){ System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); } } public static void main(String args[]){ Runnable_demo demo=new Runnable_demo(); //基于火车票创建三个窗口 new Thread(demo,"a").start(); new Thread(demo,"b").start(); new Thread(demo,"c").start(); } }
プログラムの出力は次のようになります:
2. 同期ブロックを使用して上記の例を変更します:
package com.pakage.ThreadAndRunnable; public class Runnable_demo implements Runnable{ private int ticket=10; public Runnable_demo(){ } @Override public void run() { for(int i=0;i<20;i++){ <span style="color:#ff0000">synchronized</span>(this){ if(this.ticket>0){ //休眠1s秒中,为了使效果更明显,否则可能出不了效果 try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); } } } } public static void main(String args[]){ Runnable_demo demo=new Runnable_demo(); //基于火车票创建三个窗口 new Thread(demo,"a").start(); new Thread(demo,"b").start(); new Thread(demo,"c").start(); } }
以上がJava同期ロック(同期)のサンプルコード共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。