如何实现同步Java方法

How to implement synchronised Java method

我是多线程的新手,正在尝试创建一个多线程 java 预订系统。代理商可以预订座位并可以选择多家航空公司。这是我的经纪人 class:

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 class 中的一个同步方法,是这样的:

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;
}

然后我尝试通过创建两个代理实例来测试我的主要方法中的代码,每个代理实例都尝试进行预订:

    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 中多线程的新手,非常感谢一些指导,谢谢。

同一对象上的同步方法不能同时运行。

您有两个不同的预订对象。它们的同步是相互独立的。

解决此问题的一种方法是使用同步方法创建一个 ReservationSystem class 来预订座位——并为多个预订实例创建一个实例。

public class ReservationSystem {
   public synchronized boolean reserveSeat( Reservation reservation ) {
      ...
   }
}

来自 Java tutorial on synchronized methods,并强调:

First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.