读书人

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

发布时间: 2012-03-09 21:42:53 作者: rapoo

关于线程的锁的一个问题
///////////////////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就可以结束,但是第二个没有结束似乎在等待别人的唤醒,你看看有没帮助吧

读书人网 >J2SE开发

热点推荐