我是多线程的新手,我正在尝试创建一个多线程的Java预订系统。代理商可以预订座位并可选择多家航空公司。这是我的Agent类:
public class Agent implements Runnable {
private int id;
private Reservation reservation;
public Agent() {
}
public Agent(Reservation reservation) {
this.reservation = reservation;
}
@Override
public void run() {
try {
reservation.reserveSeat();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
reserveSeat是Reservation类中的同步方法,如下所示:
public synchronized boolean reserveSeat() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " entered.");
List<Seat> availableSeats = airline.getAvailableSeats();
// if there are no available seats
while (availableSeats.isEmpty())
wait();
Seat seat;
// repeat this until an available seat is chosen
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
do {
System.out.println("Please choose from the following available seats: ");
for (Seat s : availableSeats) {
System.out.print(s.getNumber() + " ");
}
System.out.println();
String input = reader.readLine();
int seatNum = Integer.parseInt(input);
seat = airline.getSeatObjectWithNumber(seatNum);
} while (!availableSeats.contains(seat));
this.seat = seat;
// enter passenger details
System.out.println("Please enter the passenger's name. ");
// create passenger instance
String name = reader.readLine();
this.passenger = new Passenger(name);
// change seat status to reserved
seat.setReserved(true);
// add this reservation to the list of reservations the airline has
airline.getReservations().add(this);
notifyAll();
System.out.println(Thread.currentThread().getName() + " leaving.");
System.out.println("----------------------------------------------");
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
然后我尝试通过创建两个代理实例来尝试在我的main方法中测试我的代码,每个代理实例都尝试进行预订:
Reservation reservation1 = new Reservation(airline1);
Agent agent1 = new Agent(reservation1);
new Thread(agent1).start();
Reservation reservation2 = new Reservation(airline2);
Agent agent2 = new Agent(reservation2);
new Thread(agent2).start();
但是,出于某种原因,输出看起来像这样:
Thread-0 entered.
Thread-1 entered.
Please choose from the following available seats:
1 2 3
Please choose from the following available seats:
1 2 3
我不确定为什么第一个线程Thread-0没有阻止Thread-1进入监视器。就像我说我是Java新手,我非常感谢一些指导,谢谢。
答案 0 :(得分:1)
同一对象上的同步方法无法同时运行。
您有两个不同的Reservation对象。它们的同步是相互独立的。
解决此问题的一种方法是使用同步方法创建一个ReservationSystem
类来预留座位 - 并为多个预留实例创建一个实例。
public class ReservationSystem {
public synchronized boolean reserveSeat( Reservation reservation ) {
...
}
}
来自Java tutorial on synchronized methods,更加强调:
首先,两个同步方法的调用不可能在同一个对象上进行交错。当一个线程正在为对象执行同步方法时,所有其他线程都会调用同一对象的同步方法阻塞(暂停执行),直到第一个线程完成对象为止。