Java-wait()与notify()

这里运用产品-店员-消费者的例子来说明这两个函数

店员类

/** * @ClassName: Clerk * @Author: Leo * @Description: 店员 * @Date: 2019/5/2 22:44 */
public class Clerk {
    /** * 只持有一个产品 -1代表没有产品 */
    private int product = -1;

    /** * 接收产品 * * @param product */
    public synchronized void setProduct(int product) throws InterruptedException {
        waitIfFull();
        this.product = product;
        System.out.printf("生产者设定 (%d) %n", this.product);
        //通知等待集合中的线程(如消费者)
        notify();
    }

    /** * 看看店员是否有空间接受产品 没有空间的话就进入等待 * * @throws InterruptedException */
    private synchronized void waitIfFull() throws InterruptedException {
        while (this.product != -1) {
            wait();
        }
    }

    /** * @return 交货 * @throws InterruptedException */
    public synchronized int getProduct() throws InterruptedException {
        waitIfEmpty();
        //准备交货
        int pro = this.product;
        //表示货物被取走
        this.product = -1;
        System.out.printf("消费者取走 (%d)%n", pro);
        //通知等待集合中的线程(例如生产者)
        notify();
        //交货
        return pro;
    }

    /** * 查看店员是否有货 没货的话就等待 * * @throws InterruptedException */
    private void waitIfEmpty() throws InterruptedException {
        while (this.product == -1) {
            wait();
        }
    }

}

产品类

/** * @ClassName: Producer * @Author: Leo * @Description: 生产者 * @Date: 2019/5/2 22:43 */
public class Producer implements Runnable {
    private Clerk clerk;

    public Producer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println("生产者开始生产整数...");
        for (int i = 1; i <= 10; i++) {
            try {
                //将产品交给店员
                clerk.setProduct(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

消费者

/** * @ClassName: Consumer * @Author: Leo * @Description: 消费者 * @Date: 2019/5/2 22:44 */
public class Consumer implements Runnable {
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println("消费者开始消耗整数...");
        for (int i = 1; i <= 10; i++) {
            try {
                //从店员取走产品
                clerk.getProduct();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

测试类

public class Main {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        new Thread(new Producer(clerk)).start();
        new Thread(new Consumer(clerk)).start();
    }
}

输出结果

生产者开始生产整数...
消费者开始消耗整数...
生产者设定 (1) 
消费者取走 (1)
生产者设定 (2) 
消费者取走 (2)
生产者设定 (3) 
消费者取走 (3)
生产者设定 (4) 
消费者取走 (4)
生产者设定 (5) 
消费者取走 (5)
生产者设定 (6) 
消费者取走 (6)
生产者设定 (7) 
消费者取走 (7)
生产者设定 (8) 
消费者取走 (8)
生产者设定 (9) 
消费者取走 (9)
生产者设定 (10) 
消费者取走 (10)
全部评论

相关推荐

不愿透露姓名的神秘牛友
11-27 10:28
点赞 评论 收藏
分享
双非坐过牢:非佬,可以啊10.28笔试,11.06评估11.11,11.12两面,11.19oc➕offer
点赞 评论 收藏
分享
11-09 11:01
济南大学 Java
Java抽象带篮子:外卖项目真得美化一下,可以看看我的详细的外卖话术帖子
点赞 评论 收藏
分享
手撕没做出来是不是一定挂
Chrispp3:不会,写出来也不一定过
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务