나는 순환 큐와 스레딩을 사용하여 열차를 타고 올라가고 승객을 떨어 뜨리는 프로젝트를 만들고있다. Object.notify와 Object.wait을 사용하여 스레드를 제어하고 있습니다. 나는 응용 프로그램을 스레딩에 새로운 오전과 내가 이해하지 못하는이 오류가 무엇입니까 : 여기Java threading, monitor etc .... 내 머리를 감싸는 것.
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;
}
}
은 그것이 기차를 기다리는 동안 역 탑승 기차에가는 승객을 생성하는 내 역 클래스 :
import java.util.Random;
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);
}
}
}
이 프로그램의 실행 제어는 열차와 스테이션 개체간에 .wait(); 및 .notify(); 스레딩을 처리하는 훨씬 더 우아한 방법이 있다는 느낌이 들었습니다 ... 왜 .notify()에 모니터가 있습니까? 내 경우 스레딩을 처리하는 더 좋은 방법이 있습니까? 이것들이 어리석은 질문이라면 미안합니다.