Мне трудно понять многопоточность. К сожалению, это одно из заданий, которое мне нужно выполнить, чтобы пройти курс.
Речь идет о поезде: - Поезд ждет, пока Пассажирский поток отправит несколько пассажиров, пока не будет достигнута вместимость.
Затем поезд отправляется в путь. В этот период пассажиры не могут сесть в поезд.
Следующий шаг — отключение, это процедура, вызываемая потоком 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)
at 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
Ask Question
. - person David Schwartz   schedule 12.08.2015