【发布时间】:2015-11-04 20:52:48
【问题描述】:
我很难理解多线程。不幸的是,这是我通过课程需要提交的作业之一。
这是关于火车的: -火车等待乘客线程发送一些乘客,直到达到容量。
然后火车去兜风。在此期间,没有乘客可以上车。
下一步是下机,这是一个由Passenger线程调用的过程。
一旦发生这种情况,其余乘客将继续循环。
我在卸载部分遇到问题,有时我会遇到数组越界的异常。
这是错误:
乘客 3 已登上火车
乘客 0 已上车
乘客 1 已上车
乘客 12 已登上火车
乘客 13 已登上火车
满员
座位:0 乘客:3
座位:1 名乘客:0
座位:2 乘客:1
座位:3 名乘客:12
座位:4 乘客:13
开始骑行
骑行结束
乘客 3 想下车。座位:0
乘客:3下火车
剩余乘客:0
剩余乘客:1
线程“Thread-16”中的异常 java.lang.ArrayIndexOutOfBoundsException:-1
在 java.util.ArrayList.elementData(未知来源)
在 java.util.ArrayList.remove(未知来源)
在 parque.Train.unboardTrain(Train.java:104)
在 parque.Passenger.run(Passenger.java:23)
剩余乘客:12
离开的乘客:13
乘客 15 想下车。 SEAT: -1 //没有乘客ID 15吧?
我想知道如何避免这种异常?,我在想也许实施另一个与火车锁分开的锁,负责门,或者这应该作为一个条件实施?,帮助请
代码如下:
public class Train extends Thread {
private int id;
private int capacity;
private ArrayList<Integer> passengers;
private Lock l = new ReentrantLock();
private Condition trainFull = l.newCondition();
private Condition boardTrain = l.newCondition();
private Condition UnboardTrain = l.newCondition();
private boolean canBoard = true;
private boolean canUnboard = false;
//se definen los constructores
public Train(int id, int capacity) {
this.id = id;
this.capacity = capacity;
this.passengers = new ArrayList<Integer>(capacity);
}//fin constructor
public Train(int id) {
this.id = id;
this.capacity = 5;
passengers = new ArrayList<Integer>(capacity);
}//fin constructor
public void boardTrain(int passengerId) {
l.lock();
try{
while(!canBoard)
boardTrain.await();
if (passengers.size() == capacity) {
canBoard = false;
trainFull.signal();
} else {
passengers.add(passengerId);
System.out.println("Passenger " + passengerId +" has boarded the train");
}//if
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("Exception at boarding");
}finally{
l.unlock();
}//try
}//fin subir
public void waitsFullTrain() { //waits until n (capacity) passengers board the train
l.lock();
try{
trainFull.await();
System.out.println("TRAIN FULL");
for(int i = 0; i< passengers.size(); i++){
System.out.println(" SEAT: " + i + " Passenger: " + passengers.get(i));
}//for
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
l.unlock();
}//try
}//fin esperaLleno
public void goForRide() throws InterruptedException{
l.lock();
try{
System.out.println("RIDE STARTS");
Thread.sleep(2000);
System.out.println("RIDE ENDS");
canUnboard = true;
UnboardTrain.signalAll();
}finally{
l.unlock();
}
}//fin darVuelta
public void unboardTrain(int pasajeroId) {
l.lock();
try{
while(!canUnboard)
UnboardTrain.await();
//System.out.println("Bajando..");
if(passengers.size() >0){
System.out.println("Passenger "+ pasajeroId + " wants to get off the train. SEAT: "+passengers.indexOf(pasajeroId) );
passengers.remove(passengers.indexOf(pasajeroId));
System.out.println(" Passenger: " + pasajeroId + " off the train");
for (int i = 0; i<passengers.size();i++){
System.out.println(" Passenger(s) left: "+passengers.get(i));
}
}else{
System.out.println();
canUnboard = false;
canBoard = true;
boardTrain.signalAll();
}//if
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("Exception at unboarding");
}finally{
l.unlock();
}//try
}//fin bajar
public int id() {
return id;
}//fin id
@Override
public void run() {
while(true){
this.waitsFullTrain();
try {
this.goForRide();
} catch (InterruptedException e) {
e.printStackTrace();
}
}//fin while
}//fin run
}//fin clase
public class Passenger extends Thread{
private int id;
private Train t;
public Passenger(int id, Train t) {
this.id = id;
this.t = t;
}
@Override
public void run() {
t.boardTrain(this.id);
t.unboardTrain(this.id);
}//run
}//Passenger
public class Main {
public static void main(String[] args) {
Train t = new Train(1);
Passenger[] p = new Passenger[20];
for (int i = 0; i < p.length; i++) {
p[i]= new Passenger(i, t);
}//for
t.start();
for (int i = 0; i < p.length; i++) {
p[i].start();
}//for
try {
t.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for (int i = 0; i < p.length; i++) {
try {
p[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}//for
}//main
}//clase
【问题讨论】:
-
请发布堆栈跟踪。
-
在我看来,这个设计中的模型有点不对劲。想想现实世界......当车门关闭或火车不在车站时,乘客无法上下车(那些应该是你的锁)。当门打开时,unboard(), board()... 当超时发生时,关门 & 火车出发。
-
你忘了问问题!问一个实际的、具体的问题真的很重要。这就是为什么您按下的按钮被标记为
。 -
谢谢戴夫,我会尝试使用你的建议。
-
对不起,大卫,已经纠正了,干杯
标签: java multithreading conditional-statements explicit locks