2017-11-21 5 views
0

간단한 Java 스레드 코드를 동시 잠금 API로 대체하려고합니다. 여기에 물어 보는 것은 어리석은 짓 일지 모르지만 나는 내 자신을 시험했으며 어떤 성공도 얻을 수 없었습니다. 다음과 같은 수업이 있습니다. Hotel.javaJava 동시 API 잠금 vs 공유 리소스에서 동기화 됨

public class Hotel implements Runnable { 
    private Item item; 

    Hotel(Item item) { 
     this.item = item; 
    } 

    @Override 
    public void run() { 
     synchronized (item) { 
      try { 
       System.out.println("Ordered item = " + item.name); 
       Cook cook = new Cook(item); 
       Thread t = new Thread(cook); 
       t.start(); 
       Thread.sleep(1000); 
       item.wait(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("total bill: " + item.price); 
     } 
    } 

} 

Cook.java

public class Cook implements Runnable { 

    private Item item; 

    Cook(Item item) { 
     this.item = item; 
    } 

    @Override 
    public void run() { 
     synchronized (item) { 

      try { 
       System.out.println("Cooked item = " + item.name); 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      item.notify(); 
     } 

    } 
} 

및 Item.java

내가 이것을 실행하면 내가 Main.java 클래스

public class Main { 

    public static void main(String... args) { 
     Item item = new Item("Burger", 100.00); 
     Thread t = new Thread(new Hotel(item)); 
     t.start(); 

    } 

} 

다음 한

public class Item { 

    String name; 
    double price; 

    public Item(String name, double price) { 
     this.name = name; 
     this.price = price; 
    } 

} 

주류 나는 아래에있다. 놓다.

Ordered item = Burger 
Cooked item = Burger 
total bill: 100.0 

이 코드를 jdk1.5의 동시 잠금 API를 사용하여 바꿔야합니다. synchronized 키워드 대신 Lock을 사용하려고했지만 ReentrantLock을 사용하여 호텔 및 요리사와 같은 두 개의 다른 클래스에서 항목을 잠글 수 없습니다. Item은 Hotel과 Cook 사이의 공유 리소스이므로 잠글 수 있어야합니다. IllegalMonitorStateException 예외가 발생했습니다. 누구든지 이걸 도와 주실 래요?

+0

synchronized (item) { ... item.notify(); } 

? – alfasin

+0

그래서 호텔은 요리사에게 항목을 요리하도록 요청한 다음 요리사가 끝나면 호텔에서 음식을 제공하고 청구서를 인쇄합니다. 이것이 그 일을하기로되어있는 것입니까? – markspace

+0

예. 맞습니다. 그리고 그것은 순서에 있어야합니다. –

답변

1

당신은 무엇을 누락하면 또한 기본적으로 당신이

java.lang.Object.wait(); and 
java.lang.Object.notify(); 

그래서

java.util.concurrent.locks.Condition.await(); and 
java.util.concurrent.locks.Condition.signal(). 

로 대체 할 수

java.util.concurrent.locks.Condition 

를 사용할 필요가있다 당신은

에 항목을 변경하는 경우
public class Item { 
    Lock lock = new ReentrantLock(); 
    Condition condition = lock.newCondition(); 

    String name; 
    ... 
} 

당신은 대체 할 수

item.lock.lock(); 
try { 
    ... 
    item.condition.await(); 
} finally { 
    item.lock.unlock(); 
} 

및 교체와

synchronized (item) { 
    ... 
    item.wait(); 
} 

: 당신이 시도하고 어디 실패 무엇

item.lock.lock(); 
try { 
    ... 
    item.condition.signal(); 
} finally { 
    item.lock.unlock(); 
}