首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

关于线程的锁的一个有关问题

2012-03-09 
关于线程的锁的一个问题///////////////////Airport.javaimportjava.awt.*importjava.io.*importjava.ut

关于线程的锁的一个问题
///////////////////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.java

import   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


---------------------------------------------

不知道到底是什么原因报这个错误呀,怎么解决呢?




[解决办法]
调用wait()方法时,要先获得锁



synchronized (lock){
wait();
}

注:wait()和notify()要用一个锁,调用notify()也要先获得锁
[解决办法]
在airport这个对象里 不要执行其他对象的wait,只能执行自己的wait
不然会说你不是owner
如果飞机场的各种资源需要互斥,那么应该让airport调用wait 而不是plane,因为是在使用飞机场的资源上出现冲突,而不是飞机出现冲突
[解决办法]
在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就可以结束,但是第二个没有结束似乎在等待别人的唤醒,你看看有没帮助吧

热点排行