2017-11-21 4 views
0

シンプルなJavaスレッドコードをその並行ロックAPIに置き換えようとしています。 ここで尋ねるのは馬鹿なことかもしれませんが、私は自分自身で試してみると成功しませんでした。 私は以下のクラスを持っています。 Hotel.javaJavaの同時APIロックと共有リソースの同期化

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を使用して2つの異なるクラス(ホテルやCookなど)でアイテムをロックできませんでした。 ItemはHotelとCookの間の共有リソースなので、ロックする必要があります。 IllegalMonitorStateException例外が発生しました。誰でもこの上で私を助けてくれる?

+0

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

? – alfasin

+0

ホテルはホテルに料理を依頼し、料理が終わるとそのホテルにアイテムを提供して請求書を印刷します。それはこれがやるべきことですか? – markspace

+0

はい。そしてそれは順序でなければなりません。 –

答えて

1

何が欠けていることは、あなたも、あなたが

に項目を変更する場合は基本的にあなたがそう

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

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

を置き換えることができます

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(); 
} 
関連する問題