wait()方法和notify()方法的典型应用-生产者与消费者

释放双眼,带上耳机,听听看~!

在多线程开发中最典型的应用就是生产者与消费者案例,主要用到的方法就是wait()方法和notify()方法。下面我们先看一下它们具体的业务代码。

/**
 * 库存
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 11:43
 * @since 1.0.0
 */
public class Stock {

    private List<JSONObject> stocks = Collections.synchronizedList(new ArrayList<JSONObject>());

    /**
     * 生产
     *
     * @param jsonObject
     */
    public void produce(JSONObject jsonObject) {
        try {
            synchronized (stocks) {
                if (stocks.size() >= 10) {
                    stocks.wait();
                }
                if (stocks.size() > 0) {
                    stocks.notify();
                }
                stocks.add(jsonObject);
                System.out.println(String.format("库存:%s	生产:json: %s	thread: %s", stocks.size(), jsonObject.toJSONString(), Thread.currentThread().getName()));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 消费
     *
     * @param jsonObject
     */
    public void consume(JSONObject jsonObject) {
        try {
            synchronized (stocks) {
                if (stocks.size() == 0) {
                    stocks.notify();
                    stocks.wait();
                }
                stocks.remove(jsonObject);
                System.out.println(String.format("库存:%s	消费:json: %s	thread: %s", stocks.size(), jsonObject.toJSONString(), Thread.currentThread().getName()));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
/**
 * 生产者
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 11:55
 * @since 1.0.0
 */
public class Producer extends Thread {

    private Stock stock;

    public Producer(Stock stock) {
        this.stock = stock;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 15; i++) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("name", String.format("奔驰-%s", i));
            stock.produce(jsonObject);
        }
    }
}
/**
 * 消费者
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 11:55
 * @since 1.0.0
 */
public class Customer extends Thread {

    private Stock stock;

    public Customer(Stock stock) {
        this.stock = stock;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 15; i++) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("name", String.format("奔驰-%s", i));
            stock.consume(jsonObject);
        }
    }
}
/**
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 13:35
 * @since 1.0.0
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Stock stock = new Stock();
        Producer producer = new Producer(stock);
        Customer customer = new Customer(stock);
        producer.start();
        Thread.sleep(1000);
        for (int i = 3; i > 0; i--) {
            System.out.println(String.format("倒计时:%s", i));
            Thread.sleep(1000);
        }
        customer.start();
    }
}
库存:1	生产:json: {"name":"奔驰-1"}	thread: Thread-0
库存:2	生产:json: {"name":"奔驰-2"}	thread: Thread-0
库存:3	生产:json: {"name":"奔驰-3"}	thread: Thread-0
库存:4	生产:json: {"name":"奔驰-4"}	thread: Thread-0
库存:5	生产:json: {"name":"奔驰-5"}	thread: Thread-0
库存:6	生产:json: {"name":"奔驰-6"}	thread: Thread-0
库存:7	生产:json: {"name":"奔驰-7"}	thread: Thread-0
库存:8	生产:json: {"name":"奔驰-8"}	thread: Thread-0
库存:9	生产:json: {"name":"奔驰-9"}	thread: Thread-0
库存:10	生产:json: {"name":"奔驰-10"}	thread: Thread-0
倒计时:3
倒计时:2
倒计时:1
库存:9	消费:json: {"name":"奔驰-1"}	thread: Thread-1
库存:8	消费:json: {"name":"奔驰-2"}	thread: Thread-1
库存:7	消费:json: {"name":"奔驰-3"}	thread: Thread-1
库存:6	消费:json: {"name":"奔驰-4"}	thread: Thread-1
库存:5	消费:json: {"name":"奔驰-5"}	thread: Thread-1
库存:4	消费:json: {"name":"奔驰-6"}	thread: Thread-1
库存:3	消费:json: {"name":"奔驰-7"}	thread: Thread-1
库存:2	消费:json: {"name":"奔驰-8"}	thread: Thread-1
库存:1	消费:json: {"name":"奔驰-9"}	thread: Thread-1
库存:0	消费:json: {"name":"奔驰-10"}	thread: Thread-1
库存:1	生产:json: {"name":"奔驰-11"}	thread: Thread-0
库存:2	生产:json: {"name":"奔驰-12"}	thread: Thread-0
库存:1	消费:json: {"name":"奔驰-11"}	thread: Thread-1
库存:0	消费:json: {"name":"奔驰-12"}	thread: Thread-1
库存:1	生产:json: {"name":"奔驰-13"}	thread: Thread-0
库存:0	消费:json: {"name":"奔驰-13"}	thread: Thread-1
库存:1	生产:json: {"name":"奔驰-14"}	thread: Thread-0
库存:2	生产:json: {"name":"奔驰-15"}	thread: Thread-0
库存:1	消费:json: {"name":"奔驰-14"}	thread: Thread-1
库存:0	消费:json: {"name":"奔驰-15"}	thread: Thread-1

我们主要的逻辑是开启两个线程一个是生产线程一个是消费线程。当生产线程生产的库存超过10个时,暂停执行,目的是怕生产过剩。这时就只有一个消费线程在执行。当消费线程消费到库存为0时暂停消费线程,因为库存为0时不能在继续消费了。除了暂停消费线程外还调用了notify()方法目的是让生产线程继续生产。这时只有一个生产线程在执行,当生产线程生产库存大于0时,继续调用notify()方法,目的是让消费线程执行,因为库存不为0可以消费。这些就有两个线程同时执行了,这就是典型的生产者与消费者案例。

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧