多线程让我的头围绕Java线程,监视器等。。。。
我正在做一个项目,我需要循环排队和穿线来模拟火车上下乘客。我正在使用对象。通知并反对。等待以控制线程。我是线程应用程序的新手,我遇到了一个我不理解的错误:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at Station.run(Station.java:37)
at java.lang.Thread.run(Unknown Source)
这是我的主要任务
public static void main(String[] args)
{
Track theTrack = new Track();
Station[] stations = {new Station(TRAIN_STATION_TYPE.ASHMONT)};
Train[] trains = {new Train(TRAIN_TYPE.A_TRAIN, theTrack)};
Thread[] stationThreads = new Thread[stations.length];
Thread[] trainThreads = new Thread[trains.length];
theTrack.setStations(stations);
theTrack.setTrains(trains);
for(int i = 0; i<stations.length; i++)
{
stationThreads[i] = new Thread(stations[i]);
stationThreads[i].start();
}
for(int i = 0; i<trains.length; i++)
{
trainThreads[i] = new Thread(trains[i]);
trainThreads[i].start();
}
}
这是我的火车班,它将沿着轨道移动到每个车站上下乘客:
public class Train implements Runnable
{
TRAIN_TYPE trainType;
int location;
private boolean goingForward, trainIsRunning;
private Track track;
private CircularQueue <Passenger> passengers;
private Station stationBoarded;
Train()
{
this(null);
}
Train(TRAIN_TYPE trainType)
{
this(trainType, null);
}
Train(TRAIN_TYPE trainType, Track track)
{
this.trainType = trainType;
location = trainType.location();
this.track = track;
trainIsRunning = true;
goingForward = true;
}
@Override
public void run()
{
while(trainIsRunning)
{
moveTrain();// train is moving up or down the track until it hits the location of a station
setStationBoarded(track.arriveAtStation(location)); // board station
stationBoarded.queueTrain(this);// queue this train
justWait(); // wait to be notified
unloadPassengers();// unload passengers
stationBoarded.notify();//notify station boarded to allow passengers to board the train.
justWait(); // wait to be notified to leave
depart();
}
}
public boolean boardTrain(Passenger p)
{
if(!passengers.reachedCapacity())
{
passengers.enqueue(p);
return true;
}
return false;
}
public void moveTrain()
{
while(track.arriveAtStation(location) == null)
{
TIME_CONSTANT.TRAIN_MOVE_TIME.sleepAWhile();
if(goingForward)
location++;
else
location--;
if(!track.isOnTrack(location))
goingForward = !goingForward;
}
}
public void unloadPassengers()
{
for(int i = 0; i<passengers.getLength(); i++)
{
if(passengers.peekAtIndex(i).getDestination() == stationBoarded.getTrainStation())
stationBoarded.queuePassenger(passengers.remove(passengers.peekAtIndex(i)));
}
}
public synchronized void justWait()
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void depart()
{
this.stationBoarded = null;
}
public synchronized Passenger leaveTrain()
{
return passengers.dequeue();
}
public boolean isTrainIsRunning() {
return trainIsRunning;
}
public void setTrainIsRunning(boolean trainIsRunning) {
this.trainIsRunning = trainIsRunning;
}
public int getLocation() {
return location;
}
public void setLocation(int location) {
this.location = location;
}
public int getCapacity()
{
return this.trainType.capacity();
}
public Station getStationBoarded()
{
return stationBoarded;
}
public void setStationBoarded(Station stationBoarded) {
this.stationBoarded = stationBoarded;
}
public boolean trainIsEmpty()
{
return this.passengers.isEmpty();
}
public boolean trainHasReachedCapacity()
{
return passengers.reachedCapacity();
}
public Track getTrack() {
return track;
}
public void setTrack(Track track) {
this.track = track;
}
}
这是我的station类,它在等待火车进站时生成乘客上车:
导入java。util。随机的
public class Station implements Runnable
{
CircularQueue <Passenger> passengers;
CircularQueue <Train> trains;
TRAIN_STATION_TYPE trainStation;
Train trainInStation;
int location, numOfPassengers;
Passenger tempPassenger;
Random ran = new Random();
Station()
{
this (null);
}
Station(TRAIN_STATION_TYPE tranStation)
{
this(tranStation, null);
}
Station(TRAIN_STATION_TYPE trainStation, Train train)
{
this.trainStation = trainStation;
this.trainInStation = train;
this.trains = new CircularQueue();
this.passengers = new CircularQueue();
}
public void run()
{
while(trains.isEmpty())
{
genPassengers();
}
while(!trains.isEmpty())
{
trainInStation = trains.dequeue();
trainInStation.notify(); // notify the train to let the passengers off
justWait(); // wait for train to unload passengers
unloadPassengers();
trainInStation.notify();//notify the train to depart
departTrain();
}
}
public void genPassengers()
{
TIME_CONSTANT.PASSENGER_GEN_TIME.sleepAWhile();
passengers.enqueue(new Passenger());
}
public void departTrain()
{
trainInStation = null;
}
public void arrive(Train train)
{
this.trainInStation = train;
}
public Train depart()
{
Train tempTrain = this.trainInStation;
this.trainInStation = null;
return tempTrain;
}
public int getLocation() {
return location;
}
public void setLocation(int location) {
this.location = location;
}
public boolean isBoarded()
{
return (trainInStation != null);
}
public Train getTrain() {
return trainInStation;
}
public void setTrain(Train train) {
this.trainInStation = train;
}
public synchronized void queueTrain(Train train) {
trains.enqueue(train);
}
public synchronized Train dequeue() {
return trains.dequeue();
}
public synchronized void queuePassenger(Passenger passenger){
passengers.enqueue(passenger);
}
public synchronized Passenger dequeuePassenger()
{
return passengers.dequeue();
}
public TRAIN_STATION_TYPE getTrainStation() {
return trainStation;
}
public void setTrainStation(TRAIN_STATION_TYPE trainStation) {
this.trainStation = trainStation;
}
public void justWait()
{
try {
this.wait(); //wait for passengers to get off
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void unloadPassengers()
{
// for(int i = 0; i<passengers.getLength() && !trainInStation.trainHasReachedCapacity(); i++)
// {
// trainInStation.boardTrain(passengers.dequeue());
// }
while(!passengers.isEmpty() && trainInStation.getCapacity()>numOfPassengers)
{
Passenger temp = dequeuePassenger();
System.out.println(temp.toString() + " got on train " + this.trainInStation.trainType.getName());
trainInStation.boardTrain(temp);
}
}
}
正如您所看到的,通过使用,可以控制列车和车站对象之间的程序流的执行。等待();和通知();。我有一种感觉,有一种更优雅的方式来处理线程。。。为什么呢。notify()上有监视器吗?在我的情况下,有没有更好的方法来处理线程?如果这些是愚蠢的问题,对不起
# 1 楼答案
如果不先获取对象的锁,就不能调用notify或等待对象
在车站。爪哇,你在给火车站打电话。在run()方法中使用notify(),但代码块不会与trainStation同步
将调用wait或notify的代码块与正在调用wait或notify的对象同步,立即出现的问题就会消失
# 2 楼答案
您需要在wait()调用周围添加一个同步块
# 3 楼答案
这试图告诉您,您正在对一个对象调用notify,而不在该对象的
synchronized
块内。它可能在这里:您需要将其与以下内容同步:
或者是其中之一:
基本上是你称之为
notify()
或notifyAll()
的任何地方