2017-04-26 3 views
0

멀티 스레딩을 처음 사용하고 멀티 스레딩 java 예약 시스템을 만들려고합니다. 대리인은 좌석을 예약 할 수 있으며 여러 항공사를 선택할 수 있습니다. 이건 내 에이전트 클래스 :동기화 된 Java 메소드 구현 방법

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는 예약 클래스의 동기화 방법과 같은 것이다 : 나는 다음에 내 코드를 테스트하려고

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(); 

Howeve 어떤 이유로 출력이 다음과 같이 보입니다.

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에서 멀티 스레딩을 처음 사용한다고 말했듯이 몇 가지 지침을 고맙게 생각합니다.

+3

두 개의 별도 예약 ​​클래스를 인스턴스화하므로 두 스레드가 경쟁하지 않습니다. 하나의 예약 클래스를 인스턴스화하여 두 에이전트 모두에게 제공하십시오. – Code4aliving

+1

그 작품, 고마워요 @ BradBales! 이 예제에서는 각 예약에 대해 새 Reservation 인스턴스를 만들고, 예약 인스턴스를 매개 변수로 사용하는 동기화 된 메서드로 새 ReservationSystem 클래스를 만드는 것이 더 바람직하다고 생각합니다. @Andy Thomas가 대답에서 제안했습니다. – sums22

답변

1

동기화 된 방법 동일한 개체은 동시에 실행할 수 없습니다.

두 개의 서로 다른 예약 개체가 있습니다. 동기화는 서로 독립적입니다.

이 문제를 해결하는 한 가지 방법은 좌석을 예약하기 위해 synchronized 메서드를 사용하여 ReservationSystem 클래스를 만들고 여러 예약 인스턴스에 대해 하나의 인스턴스를 만드는 것입니다. 추가 중시 한 Java tutorial on synchronized methods 가입일

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

:

첫째, 그것은 인터리빙하는 동일한 개체에 동기화 방법 두 호출 불가능하다. 한 스레드가 객체에 대해 동기화 된 메소드를 실행할 때 첫 번째 스레드가 객체로 완료 될 때까지 동일한 객체 블록 (실행 중단)에 대해 동기화 된 메소드를 호출하는 다른 모든 스레드.

+0

그것은 많은 의미가 있습니다, 대단히 감사합니다 :) – sums22