2017-11-21 4 views
0

Ich versuche, den einfachen Java-Thread-Code mit seiner API gleichzeitige Sperre zu ersetzen. Es könnte das dumme sein, es hier zu fragen, aber ich habe es selbst versucht und konnte keinen Erfolg haben. Ich habe folgende Klassen. Hotel.javaJava gleichzeitige API Lock vs Synchonized auf freigegebenen Ressourcen

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

    } 
} 

und Item.java

public class Item { 

    String name; 
    double price; 

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

} 

Ich habe folgende Main.java Klasse

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

    } 

} 

Als ich das laufen Hauptklasse Ich komme unten raus stellen.

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

Ich möchte diesen Code mit gleichzeitiger Lock API von jdk1.5 ersetzen. Ich habe versucht, Lock anstelle von synchronisierten Schlüsselwort zu verwenden, aber ich war nicht in der Lage, das Element in zwei verschiedenen Klassen (z. B. Hotel und Cook) mit ReentrantLock zu sperren. Da das Item eine gemeinsame Ressource zwischen Hotel und Cook ist, sollte es möglich sein, es zu sperren. Ich habe IllegalMonitorStateException Exception erhalten. Kann mir bitte jemand dabei helfen?

+0

Was Sie versucht haben, und wo haben Sie es versäumt? – alfasin

+0

Also bittet das Hotel den Koch, einen Artikel zu kochen, und wenn der Koch fertig ist, serviert das Hotel den Artikel und druckt die Rechnung aus. Soll das was tun? – markspace

+0

ja richtig. Und es sollte in der Reihenfolge sein. –

Antwort

1

Was Ihnen fehlt, ist, dass Sie auch

java.util.concurrent.locks.Condition 

Im Wesentlichen können Sie ersetzen

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

mit

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

So verwenden müssen, wenn Sie Artikel zur

ändern
public class Item { 
    Lock lock = new ReentrantLock(); 
    Condition condition = lock.newCondition(); 

    String name; 
    ... 
} 

Sie können

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

mit

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

ersetzen und ersetzen:

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

mit

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