Java并发API锁定与共享资源上的同步

时间:2017-11-21 04:59:21

标签: java multithreading concurrency

我试图用它的并发锁API替换简单的Java线程代码。 在这里问问可能是愚蠢的事情,但我尝试了自己并且无法取得任何成功。 我有以下课程。 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();
        }

    }
}

和Item.java

public class Item {

    String name;
    double price;

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

}

我有以下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();

    }

}

当我运行这个Main类时,我得到低于输出。

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

我想使用jdk1.5的并发Lock API替换此代码。 我尝试使用Lock而不是synchronized关键字,但我无法使用ReentrantLock将项目锁定在两个不同的类(即Hotel和Cook)中。由于物品是酒店和库克之间的共享资源,我应该能够锁定它。我收到了IllegalMonitorStateException异常。

1 个答案:

答案 0 :(得分:1)

您缺少的是您还需要使用

java.util.concurrent.locks.Condition

基本上你可以替换

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

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

因此,如果您将项目更改为

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

    String name;
    ...
}

您可以替换

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

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

并替换:

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

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