生产者和消费者的实现原理

一、多线程相关知识点回顾

什么是进程

程序是指令和数据的有序集合,是一个静态概念,其本身没有任何运行的意义。进程是程序在处理机上的一次执行过程,是一个动态的概念。进程是一个具有一定独立功能的程序。进程是一个实体,每一个进程都有自己的地址空间。

进程的状态

进程执行时的间断性决定了进程具有多种状态。事实上,运行中的进程具有三种状态。

  1. 就绪状态
  2. 运行状态
  3. 阻塞状态


    Xnip2019-10-30_14-41-17.jpg

什么是线程

线程是进程的组成部分。一个进程可以有多个线程,一个线程必须有一个父进程。线程是处理器调度的基础单位。

线程实现的两种方式

Xnip2019-10-30_14-48-21.jpg

线程的状态

Xnip2019-10-30_14-50-01.jpg

二、生产者和消费者的案例分析

  1. 假设饭店里有一个厨师和一个服务员,服务员必须等到厨师准备好膳食后,才能上菜。每当厨师准备好膳食后,才会通知服务员。这是一个任务协作的示例,厨师代表生产者,服务员代表消费者。生产者不断生产产品,消费者不断消费产品,这构成了多线程开发中的一个经典案例----生产者与消费者。
  2. 实质是要解决多个线程共享一个数据时,如何处理线程安全问题。java的多线程是使用抢占式来实现的,这里我们要使用对象锁来保证线程安全。
  3. 部分代码如下
public void set(String name,String desc){
        synchronized (this) { //在对象上上锁
            if(flag==false){ //表示不能生产,所以就让出 CPU,并释放对象锁
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //表示正在生产
            this.name = name;
            try {
                //模拟生产食物的时间过程
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.desc = desc;
            flag = false;
            this.notify(); //唤醒在此对象锁上的任意一个线程
        }
}
public void get(){
        synchronized (this) {
            if(flag==true){  //表示不能消费
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //正在消费
            System.out.println(this.name + "--" + this.desc);
            flag = true;
            this.notify(); //唤醒在此对象锁上的任意一个线程
        }
    }

具体代码可参考
https://github.com/JacksonMike/Java_ultimate/blob/master/ProducerConsumerDemo.java

  1. 在这个案例中,我们需要达到的效果是:两个线程在各自调用food对象的方法的时候,要限制两个方法以互斥的方式进行,比如例如A线程调用food的set方法,那么B线程只能等到A线程完成set方法后才能调用。具体应用场景可以引申为: 一个是负责提供数据的线程,把数据拿到后放到对列,另一个不断的从队列中取出数据进行消费。

三、多进程的经典面试题

  1. 生产这消费者模型的作用是什么?
  2. sleep方法和wait方法有什么区别?
  3. 如何在两个线程之间共享数据?
  4. 为什么wait()方法和notify()要在同步块中调用?
  5. wait()方法和notify()方法在放弃对象监视器时有什么区别?
  6. Thread.sleep(0)的作用是什么?
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容