线程的通信--生产者消费者问题

sleep()wait() 有什么区别? 
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,
给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。
调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,
进入等待此对象的等待锁定池,
只有针对此对象发出notify方法(或notifyAll)
后本线程才进入对象锁定池准备获得对象锁进入运行状态。

 wait()notify()notifyAll()
 wait():令当前线程挂起并放弃CPU、同步资源并等待,使别的线程可访问并修改共享资源,而当
前线程排队等候其他线程调用notify()notifyAll()方法唤醒,唤醒后等待重新获得对监视器的所有
权后才能继续执行。
 notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
 notifyAll ():唤醒正在排队等待资源的所有线程结束等待.
 这三个方法只有在synchronized方法或synchronized代码块中才能使用,否则会报
java.lang.IllegalMonitorStateException异常。
 因为这三个方法必须有锁对象调用,而任意对象都可以作为synchronized的同步锁,
因此这三个方法只能在Object类中声明。
wait() 方法
在当前线程中调用方法: 对象名.wait()
使当前线程进入等待(某对象)状态 ,直到另一线程对该对象发出 notify
(或notifyAll) 为止。
调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)
调用此方法后,当前线程将释放对象监控权 ,然后进入等待
在当前线程被notify后,要重新获得监控权,然后从断点处继续代码的执行。
notify()/notifyAll()
在当前线程中调用方法: 对象名.notify()
功能:唤醒等待该对象监控权的一个/所有线程。
调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)

在这里插入图片描述
代码:

/**
 * 生产者消费者问题
 * 分析:
 * 1.是否是多线程问题:是,存在生产者线程,消费者线程
 * 2.是否有共享数据:是,店员,商品
 * 3.如何解决线程安全问题:同步代码块,同步锁,lock锁
 * 4.是否涉及线程通信问题。是
 * @author sun
 * @date 2021/7/16 - 16:21
 */
public class ProductTest {//测试
    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Thread Producterthread = new Thread(new Producter(clerk));
        Thread  Consumerthread = new Thread(new Consumer(clerk));

        Producterthread.start();
        Consumerthread.start();
    }
}

class Clerk{//售货员
    private int product=0;

    public synchronized  void addProduct(){//添加产品
        if (product>=20){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }else {
            product++;
            System.out.println("生产者生产了第"+product+"个产品");
            notifyAll();//唤醒正在排队等待资源的所有线程结束等待

        }
    }
    public synchronized  void getProduct(){//售出产品
        if (this.product<=0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("消费者取走了第"+product+"个产品");
            product--;
            notifyAll();
        }
    }

}
class Producter implements Runnable{//生产者
    Clerk clerk;
    public Producter(Clerk clerk){
        this.clerk=clerk;
    }


    public void run() {
        System.out.println("生产者开始生产产品");
        while (true){
            try {
                Thread.sleep((int)Math.random()*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.addProduct();
        }
    }
}

class Consumer implements Runnable{//消费者

    Clerk clerk;

    public Consumer (Clerk clerk){
        this.clerk=clerk;
    }
    public void run() {
        System.out.println("消费者开始取走产品");
        while (true) {
            try {
                Thread.sleep((int) Math.random() * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.getProduct();
        }
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值