///////////////////Airport.java
import java.awt.*;
import java.io.*;
import java.util.*;
/**
 * @author elove
 *
 */
public class Airport {
public AirportMap airportMap;
protected ThreadGroup tg;
private static Vector<Plane> runwayList=new Vector<Plane>();//#2
private static Vector<Plane> gatesList=new Vector<Plane>();//#1


public Airport(){
  Frame mapFrame;
  Panel pl;
  mapFrame=new Frame("Airport Map");
  airportMap=new AirportMap();
  pl=new Panel();
  pl.setLayout(new BorderLayout());
  pl.add("Center", airportMap);
  mapFrame.add("Center", pl);
  mapFrame.setSize(200, 300);
  mapFrame.pack();
 
  tg= new ThreadGroup("Threads");
// Old
  
  /*
  * 
  Plane planes[]=new Plane[1];
  planes[0]=new Plane(tg,0,this);
  
  try{
planes[0].join();  
  }catch(InterruptedException e){
  e.printStackTrace();
  }
  System.exit(0);*/
  
  
  
  //   New
  
  Plane planes[]=new Plane[2];
  for(int j=0;j<2;j++){
  planes[j]=new Plane(tg,j,this);
  }
  synchronized(this){
  try{
  wait(5000);
  }catch(InterruptedException e){
  e.printStackTrace();
  }
  }
  System.exit(0);
}


   private void RequestLock(Plane pl,Vector<Plane> locklist){
   boolean empty;
  
   
   synchronized(locklist){
   
   empty=locklist.isEmpty();
   locklist.addElement(pl);
   
   }
   
   if(empty==false){
     try{
     pl.wait();
     }
    
   catch(InterruptedException e){e.printStackTrace();}
   }


   
   
   public void ReleaseLock(Plane pl,Vector<Plane> lockList){
   Plane peek;// To notify a plane!
   synchronized(lockList){
  lockList.removeElement(pl);
  if (lockList.isEmpty()==false){
  try{
  peek=lockList.firstElement();
  synchronized(peek){
  peek.notify();
  }
  }catch(NoSuchElementException e){
  e.printStackTrace();
  }
  }
   }
   }
   
   public void RequestRunwayLock(Plane pl){
   RequestLock(pl,runwayList);
   }
   public void RequestGatesLock(Plane pl){
   RequestLock(pl,gatesList);  
   }
   public void ReleaseRunwayLock(Plane pl){
   ReleaseLock(pl,runwayList);
   System.out.println(pl.threadName+"ReleaseGatesLock");
   }
public void ReleaseGatesLock(Plane pl){
ReleaseLock(pl,gatesList);  
System.out.println(pl.threadName+"ReleaseRunwayLock");
   }
public static void main(String[] args){
System.out.println("Ok");
new Airport();
System.out.println("Ok");
}
}
--------------------------------------------------------------------///////////////////////AirportMap.java
import java.awt.*;
public class AirportMap extends Canvas{ /**
 * 
 */
private static final long serialVersionUID = 1L;

public void LandPlane(Plane pl){

}

public void TaxiToGate(Plane pl){

}

public void Takeoff(Plane pl){

}}
------------------------------------------------------------------------
////////////////Plane.javaimport java.awt.*;
import java.io.*;
import java.util.*;public class Plane extends Thread{
String threadName;
Airport airport;
static int timeAtGate;


  public Plane(ThreadGroup tg,int name,Airport theAirport){
  super(tg,"Plane-"+name);
  airport=theAirport;
  timeAtGate=3000;
  threadName=new String("Plane-"+name);
  this.start();
  }
  
  public void createImages(){
  
  }
  
   public void run(){
   System.out.println("Waiting to land "+threadName);
   
   /*  #2   */
   airport.RequestRunwayLock(this);
   System.out.println("Got use of runway "+threadName);
   
   System.out.println("Landing "+threadName);
   airport.airportMap.LandPlane(this);
   System.out.println("Landed "+threadName);
   
   /*  #3    */
   airport.ReleaseRunwayLock(this);
   
   
   
   /*  #1    */
   airport.RequestGatesLock(this);
   System.out.println("Got a gate "+threadName);
   
   airport.airportMap.TaxiToGate(this);
   System.out.println("At gate "+threadName);
   
   
   /*  Spend some time at the gate!   */
   try{
   sleep(timeAtGate);
   }catch(InterruptedException e){e.printStackTrace();}
   
   airport.RequestRunwayLock(this);
   System.out.println("Got runway for takeoff"+threadName);
   airport.airportMap.Takeoff(this);
   
   
   airport.ReleaseGatesLock(this);
   
   airport.ReleaseRunwayLock(this);
   
   
   System.out.println("END"+threadName);
   
   }
}
=====================================================================================================================================================编译结果:Ok
Waiting to land Plane-0
Got use of runway Plane-0
Landing Plane-0
Landed Plane-0
Plane-0ReleaseGatesLock
Got a gate Plane-0
At gate Plane-0
Waiting to land Plane-1
Got use of runway Plane-1
Landing Plane-1
Landed Plane-1
Plane-1ReleaseGatesLock
Exception in thread "Plane-1" java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:474)
at Airport.RequestLock(Airport.java:75)
at Airport.RequestGatesLock(Airport.java:104)
at Plane.run(Plane.java:40)
Got runway for takeoffPlane-0
Plane-0ReleaseRunwayLock
Plane-0ReleaseGatesLock
ENDPlane-0
---------------------------------------------不知道到底是什么原因报这个错误呀,怎么解决呢?

解决方案 »

  1.   

    调用wait()方法时,要先获得锁如synchronized (lock){
        wait();
    }注:wait()和notify()要用一个锁,调用notify()也要先获得锁
      

  2.   

    在airport这个对象里  不要执行其他对象的wait,只能执行自己的wait
    不然会说你不是owner
    如果飞机场的各种资源需要互斥,那么应该让airport调用wait 而不是plane,因为是在使用飞机场的资源上出现冲突,而不是飞机出现冲突
      

  3.   

    还有runway和gates为什么用list 呢?
    不是想实现只有一个runway和gates ,两袈飞机争用么?
    那样做Object runway,gates 就好啦, 为什么用list呢?
      

  4.   

    import java.io.*;
    import java.util.*;/**
     * @author elove
     *
     */
    // 资源互斥容器
    class MyList {
    private LinkedList queue = new LinkedList();
    public MyList(){} public MyList(int ii){
    for(int i=0; i<ii; i++){
    queue.addLast(i);
    }
    } public synchronized void enter(){
    queue.addLast("enter");
    notifyAll();
    } public synchronized void out(){
    while(queue.isEmpty()){
    try{
    wait();
    }catch(InterruptedException ie){}
    }//while
    queue.removeFirst();
    }
    }public class Airport { protected ThreadGroup tg;
    private static MyList runway= new MyList(1);
    private static MyList gates= new MyList(1);


    public Airport(){
      tg= new ThreadGroup("Threads");
      Plane planes[]=new Plane[5];
      for(int j=0;j<5;j++){
      planes[j]=new Plane(tg,j,this);
      }
    }

       public void requestRunway(){

    runway.out();
       } public void releaseRunway(){

    runway.enter();

    } public void requestGates(){

    gates.out();
    } public void releaseGates(){

    gates.enter();
    }
    public static void main(String[] args){
    System.out.println("Ok");
    new Airport();
    System.out.println("Ok");
    }

    }
    class Plane extends Thread{
    String threadName;
    Airport airport;
    static int timeAtGate;


      public Plane(ThreadGroup tg,int name,Airport theAirport){
      super(tg,"Plane-"+name);
      airport=theAirport;
      timeAtGate=3000;
      threadName=new String("Plane-"+name);
      this.start();
      }
      
      public void run(){
       System.out.println("Waiting to land "+threadName);
       airport.requestRunway();
       System.out.println("Got use of runway "+threadName);
       System.out.println("Landing "+threadName);
       System.out.println("Landed "+threadName);
       airport.releaseRunway();
       airport.requestGates();
       System.out.println("Got a gate "+threadName);
       System.out.println("At gate "+threadName);
       try{
       sleep(timeAtGate);
       }catch(InterruptedException e){e.printStackTrace();}
       airport.requestRunway();
       System.out.println("Got runway for takeoff"+threadName);
       airport.releaseGates();
       airport.releaseRunway();
       System.out.println("END"+threadName);
       }
    }
      

  5.   

    在AirPort类的RequestLock方法里,wait()方法没有获取对象锁,所以抛出异常,我改了
    import java.awt.*;
    import java.io.*;
    import java.util.*;
    /**
     * @author elove
     *
     */
    public class Airport {
    public AirportMap airportMap;
    protected ThreadGroup tg;
    private static Vector<Plane> runwayList=new Vector<Plane>();//#2
    private static Vector<Plane> gatesList=new Vector<Plane>();//#1
    public Airport(){
      Frame mapFrame;
      Panel pl;
      mapFrame=new Frame("Airport Map");
      airportMap=new AirportMap();
      pl=new Panel();
      pl.setLayout(new BorderLayout());
      pl.add("Center", airportMap);
      mapFrame.add("Center", pl);
      mapFrame.setSize(200, 300);
      mapFrame.pack();
     
      tg= new ThreadGroup("Threads");
    // Old
      
      /*
      * 
      Plane planes[]=new Plane[1];
      planes[0]=new Plane(tg,0,this);
      
      try{
    planes[0].join();  
      }catch(InterruptedException e){
      e.printStackTrace();
      }
      System.exit(0);*/
      
      //   New
      
      Plane planes[]=new Plane[2];
      for(int j=0;j<2;j++){
      planes[j]=new Plane(tg,j,this);
      }  synchronized(this){
      try{
      wait(5000);
      }catch(InterruptedException e){
      e.printStackTrace();
             }//catch
      }//synchronized
      //System.exit(0);
    }
       private void RequestLock(Plane pl,Vector<Plane> locklist){
       boolean empty;
      
       
       synchronized(locklist){
       
       empty=locklist.isEmpty();
       locklist.addElement(pl);
       
       }
      if(empty==false){
        try{   synchronized(pl){
        pl.wait();}
        }
       catch(InterruptedException e){e.printStackTrace();}
       }   
    }    
       
    public void ReleaseLock(Plane pl,Vector<Plane> lockList){
       Plane peek;// To notify a plane!
       synchronized(lockList){
      lockList.removeElement(pl);
      if (lockList.isEmpty()==false){
      try{
      peek=lockList.firstElement();
      synchronized(peek){
      peek.notify();
      }
      }catch(NoSuchElementException e){
      e.printStackTrace();
      }
      }
       }
       }
       
       public void RequestRunwayLock(Plane pl){
       RequestLock(pl,runwayList);
       }   public void RequestGatesLock(Plane pl){
       RequestLock(pl,gatesList);  
       }   public void ReleaseRunwayLock(Plane pl){
       ReleaseLock(pl,runwayList);
       System.out.println(pl.threadName+"  ReleaseGatesLock");
       }public void ReleaseGatesLock(Plane pl){
    ReleaseLock(pl,gatesList);  
    System.out.println(pl.threadName+"ReleaseRunwayLock");
       }public static void main(String[] args){
    System.out.println("Ok");
    new Airport();
    System.out.println("Ok");
    }
    }这样第一个Plane就可以结束,但是第二个没有结束似乎在等待别人的唤醒,你看看有没帮助吧