Мне сложно понять многопоточность. К сожалению, это одно из заданий, которые мне нужно подать, чтобы пройти курс.Multithread. Явные блокировки и условия
Речь идет о поезде: -Поезд ждет пассажирской темы, чтобы отправить пассажиров, пока не будет достигнута пропускная способность.
Затем поезд отправляется в путь. В течение этого периода пассажиры не могут сесть на поезд.
Следующий шаг - unboarding, это процедура, называемая потоком пассажира.
Как только это произойдет, цикл продолжается с остальными пассажирами.
У меня возникают проблемы с нерабочей частью, иногда я получаю исключение для массива за пределами.
Вот ошибка:
Пассажир 3 уже сел на поезд
Пассажир 0 имеет сел на поезд
Пассажир 1 имеет сел на поезд
Пассажир 12 имеет сел на поезд
Пассажир 13 имеет сел на поезд
ПОЕЗД ПОЛНЫЙ
СИДЕНЬЯ: 0 Пассажир: 3
сиденья: 1 Пассажир: 0
сиденья: 2 Passenge г: 1
СИДЕНЬЯ: 3 Passenger: 12
СИДЕНЬЯ: 4 Passenger: 13
RIDE НАЧИНАЕТСЯ
RIDE ЗАКАНЧИВАЕТСЯ
Пассажир 3 хочет сойти с поезда. Сиденье: 0
Пассажир: 3 с поезда
пассажира (ов) слева направо: 0
Пассажир (ы) слева направо: 1
Исключение в потоке java.lang.ArrayIndexOutOfBoundsException "Автор-16": -1
в java.util.ArrayList.elementData (Unknown Source)
в java.util.ArrayList.remove (Unknown Source)
в parque.Train.unboardTrain (Train.java:104)
в parque.Passenger.run (Passenger.java:23)
Пассажир (и): 12
Пассажир (и): 13
Пассажир 15 хочет сойти с поезда. SEAT: -1 // Нет пассажира 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
Пожалуйста, разместите stacktrace. –
Модель выглядит немного неправильно в этом дизайне для меня. Подумайте о реальном мире ... Пассажиры не могут встать или выйти из поезда, когда двери закрыты или поезд не находится на станции (это должны быть ваши замки). Когда двери открыты, unboard(), board() ... Когда происходит тайм-аут, закрываются двери и поезд. – Dave
Вы забыли задать вопрос! Очень важно, чтобы вы задали конкретный конкретный вопрос. Вот почему кнопка, которую вы нажали, помечена как «Ask Question». –