2017-06-12 8 views
1

私は、この簡単なJavaプログラムを使用して、顧客が搭乗することを可能にしています。私はwait()とnotify()文を間違った位置に置いてプログラムがデッドロックする原因になったと思いますが、自分では理解できません。以下は私が書いたコードです。Java Monitorを使用したシンプルなプログラム

public class AdultCouple extends Thread 
{ 
    private boolean onRide = false; 
    private int ID; 

    AdultCouple(int ID) 
    { 
     this.ID = ID; 
    } 

    public synchronized void getIn() 
    { 
     while (!Main.isDoorOpen) 
     { 
      try 
      { 
       wait(); 
      } 
      catch (InterruptedException ex) 
      { 

      } 
      System.out.println("Go through"); 
     } 
     System.out.println("Couple " + ID + " get in boarding area."); 
     onRide = true; 
     Main.peopleInBoardingArea++; 
     notify(); 
    } 

    public void run() 
    { 
     getIn(); 
    } 
} 


public class Area extends Thread 
{ 

    Area() 
    { 
    } 

    public synchronized void openDoor() 
    { 
     while (Main.peopleInBoardingArea != 0) 
     { 
      try 
      { 
       wait(); 
      } 
      catch (InterruptedException ex) 
      { 
      } 
     } 
     System.out.println("Area opens"); 
     Main.isDoorOpen = true; 
     notifyAll(); 
    } 

    public synchronized void closeDoor() 
    { 
    } 


    public void run() 
    { 
     openDoor(); 
    } 
} 


public class ParentKid extends Thread 
{ 

    private boolean onRide = false; 
    private int ID; 

    ParentKid(int ID) 
    { 
     this.ID = ID; 
    } 

    public synchronized void getIn() 
    { 
     while (!Main.isDoorOpen) 
     { 
      try 
      { 
       wait(); 
      } 
      catch (InterruptedException ex) 
      { 

      } 
      System.out.println("Go through"); 
     } 
     System.out.println("Couple " + ID + " get in boarding area."); 
     onRide = true; 
     Main.peopleInBoardingArea++; 
     notify(); 
    } 

    public void run() 
    { 
     getIn(); 
    } 

} 

public class Main 
{ 

    public static boolean isDoorOpen = false; 
    public static int peopleInBoardingArea = 0; 

    public static void main(String args[]) 
    { 
     Thread t3 = new Area(); 
     Thread t1 = new ParentKid(1); 
     Thread t2 = new AdultCouple(2); 


     t1.start(); 
     t2.start(); 
     t3.start(); 

     try 
     { 
      t1.join(); 
      t2.join(); 
      t3.join(); 
     } 
     catch (InterruptedException ex) 
     { 

     } 
    } 
} 
+0

1つの問題は、クラス「メイン」の静的フィールドに非同期アクセスを使用していることです。それらを 'volatile 'に変更しても' ++'演算子では機能しません。 – Andreas

答えて

0

問題は、異なるオブジェクトで同期することです。あなたがこのようなものを書くとき

public synchronized foo() {...} 

あなたはこのオブジェクトに同期させます。あなたの場合、あなたは意味をなさない現在のスレッドで同期します。同じオブジェクトで同期する必要があります。

public class Main { 

    public static Object lock = new Object(); 
    ... 
} 

public class AdultCouple extends Thread 
{ 
    private boolean onRide = false; 
    private int ID; 

    AdultCouple(int ID) 
    { 
     this.ID = ID; 
    } 

    public void getIn() 
    { 
     synchronized (Main.lock) { 
      while (!Main.isDoorOpen) { 
       try { 
        Main.lock.wait(); 
       } catch (InterruptedException ex) { 

       } 
       System.out.println("Go through"); 
      } 
      System.out.println("Couple " + ID + " get in boarding area."); 
      onRide = true; 
      Main.peopleInBoardingArea++; 
      Main.lock.notifyAll(); 
     } 
    } 

    public void run() 
    { 
     getIn(); 
    } 
} 

public class Area extends Thread 
{ 

    Area() 
    { 
    } 

    public void openDoor() 
    { 
     synchronized (Main.lock) { 
      while (Main.peopleInBoardingArea != 0) { 
       try { 
        Main.lock.wait(); 
       } catch (InterruptedException ex) { 
       } 
      } 
      System.out.println("Area opens"); 
      Main.isDoorOpen = true; 
      Main.lock.notifyAll(); 
     } 
    } 

    public synchronized void closeDoor() 
    { 
    } 


    public void run() 
    { 
     openDoor(); 
    } 
} 

public class ParentKid extends Thread 
{ 

    private boolean onRide = false; 
    private int ID; 

    ParentKid(int ID) 
    { 
     this.ID = ID; 
    } 

    public void getIn() 
    { 
     synchronized (Main.lock) { 
      while (!Main.isDoorOpen) { 
       try { 
        Main.lock.wait(); 
       } catch (InterruptedException ex) { 

       } 
       System.out.println("Go through"); 
      } 
      System.out.println("Kid " + ID + " get in boarding area."); 
      onRide = true; 
      Main.peopleInBoardingArea++; 
      Main.lock.notifyAll(); 
     } 
    } 


    public void run() 
    { 
     getIn(); 
    } 

} 

notify()もnotifyAll()も使用しないでください。

関連する問題