Reputation: 451
I am trying to replace the simple Java thread code with its concurrent lock API. It might be the silly thing to ask it here, but i tried by my self and could not get any success. I have following classes. Hotel.java
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();
}
}
}
and Item.java
public class Item {
String name;
double price;
public Item(String name, double price) {
this.name = name;
this.price = price;
}
}
I have following Main.java class
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();
}
}
When I run this Main class I get below output.
Ordered item = Burger
Cooked item = Burger
total bill: 100.0
I want to replace this code using concurrent Lock API of jdk1.5. I tried to use Lock instead of synchronized keyword, But I was not able to lock the item in two different classes(i.e. Hotel and Cook) using ReentrantLock. Since the Item is a shared resource between Hotel and Cook I should be able to lock it. I got IllegalMonitorStateException Exception.
Upvotes: 1
Views: 255
Reputation: 886
What you are missing is that you also need to use
java.util.concurrent.locks.Condition
Essentially you can replace
java.lang.Object.wait(); and
java.lang.Object.notify();
with
java.util.concurrent.locks.Condition.await(); and
java.util.concurrent.locks.Condition.signal().
So if you change Item to
public class Item {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
String name;
...
}
You can replace
synchronized (item) {
...
item.wait();
}
with
item.lock.lock();
try {
...
item.condition.await();
} finally {
item.lock.unlock();
}
and replace:
synchronized (item) {
...
item.notify();
}
with
item.lock.lock();
try {
...
item.condition.signal();
} finally {
item.lock.unlock();
}
Upvotes: 1