如何实现同步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.
我是多线程的新手,正在尝试创建一个多线程 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.