【Javaマルチスレッド】相互反発


Javaマルチスレッド学習2——相互反発
はじめに
      前のセクション(http://www.cnblogs.com/lzhen/p/3917966.html) で、Runnableインターフェースを実現することによって、マルチスレッドにおけるリソースの共有を実現し、いくつかの基本的な問題を解決しましたが、実際に使用する過程で、直接にその中の第四節の方法を使用すると、予測できない問題が発生します.今はその中のコードを少し修正します.以下の通りです.
 1 class MyThread implements Runnable  2 {  3  

 4     private int ticket = 5;  //5  

 5  

 6     public void run()  7  {  8         for (int i=0; i<=5; i++)  9  { 10             if (this.ticket > 0) 11  { 12                 System.out.println(Thread.currentThread().getName()+ "    "+this.ticket--); 13                     try

14  { 15                         Thread.sleep(500); 16  } 17                     catch (InterruptedException e) 18  { 19                         // TODO Auto-generated catch block

20  e.printStackTrace(); 21  } 22 

23  } 24  } 25  } 26     

27 } 28 public class TestThread { 29      

30     public static void main(String [] args) 31  { 32         MyThread my = new MyThread(); 33         new Thread(my, "1   ").start(); 34         new Thread(my, "2   ").start(); 35         new Thread(my, "3   ").start(); 36  } 37 }
       このコードが実行された結果は、
1 1       5 2 3       3 3 2       4 4 2       2 5 1       1 6 3       2
       もちろんこの結果には大きな不確実性があります.このような問題の原因はスレッドが同じリソースを共有している間に衝突したためです.スレッド1が共有データを変更した可能性があります.まだ出力に間に合いません.スレッド2が使用されています.このような問題は実際には許されません.相互反発はこのような臨界資源問題を解決する最も簡単な方法である.
 
 
二、synchronizedキーワード
       synchronizedキーワードは一つの修飾子であり、コードブロックと方法を修飾することができる.その役割は、同じオブジェクトに対して、異なるスレッドが同じ方法またはコードブロックを呼び出すときは、前のスレッドが実行されるのを待ってから、この方法またはコードブロックを実行することができます.synchronizedキーを使って上のコードを修正します.
 1 import java.awt.Desktop.Action;  2 

 3 

 4 class MyThread implements Runnable  5 {  6 

 7     private int ticket = 5; // 5  

 8 

 9 

10     public void run() 11  { 12         for (int i = 1; i <= 5; i++) 13  { 14             synchronized (this) 15  { 16                 if (this.ticket > 0) 17  { 18                     action(this.ticket); 19                     try

20  { 21                         Thread.sleep(500); 22  } 23                     catch (InterruptedException e) 24  { 25                         // TODO Auto-generated catch block

26  e.printStackTrace(); 27  } 28                     this.ticket--; 29 

30  } 31  } 32  } 33 

34  } 35 

36 

37     public synchronized void action(int ticket) 38  { 39         System.out.println(Thread.currentThread().getName() + "    " + ticket); 40  } 41 

42 } 43 

44 

45 public class TestThread 46 { 47 

48     public static void main(String[] args) 49  { 50         MyThread my = new MyThread(); 51         new Thread(my, "1   ").start(); 52         new Thread(my, "2   ").start(); 53         new Thread(my, "3   ").start(); 54  } 55 }
        ここでは、synchronizedの使い方をデモするために、コードの中でsynchronized修飾方法だけでなく、コードブロックを修飾するために使用されます.上記のコードの実現効果は以下の通りです.
1       5

3       4

2       3

3       2

1       1
       予想した効果と一致した.