美文网首页
多线程之生产者与消费者问题

多线程之生产者与消费者问题

作者: ihujian | 来源:发表于2017-12-15 19:39 被阅读0次

生产者消费者模式是并发、多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。

线程之间的状态转换: 线程状态.PNG

生产者和消费者模式在生活当中随处可见,它描述的是协调与协作的关系。比如一个人正在准备食物(生产者),而另一个人正在吃(消费者),他们使用一个共用的桌子用于放置盘子和取走盘子,生产者准备食物,如果桌子上已经满了就等待,消费者(那个吃的)等待如果桌子空了的话。这里桌子就是一个共享的对象。

现在用代码实现这一场景。
情景一:一个消费者和一个生产者,当生产者生产一个,消费者消费一个。
首先定义资源

package com.ihujian.thread;

/**
 * 
 * Created by Administrator on 2017/12/15.
 */
public class Resource {
    private String name;
    private int count = 1;
    private boolean flag = false;
    public synchronized void set(String name){
        if(flag){
            try {
                this.wait();
            }catch (Exception e){

            }
        }
        this.name = name + "----"+ count++;

        System.out.println(Thread.currentThread().getName() + "。。。生产者。。"+this.name);

        flag = true;
        this.notify();
    }

    public synchronized void out(){
        if(!flag){
            try {
                this.wait();
            }catch (Exception e){

            }
        }
        System.out.println(Thread.currentThread().getName() +"....消费者..."+this.name);
        flag = false;
        this.notify();
    }

}

定义生产者类

package com.ihujian.thread;

/**
 * Created by Administrator on 2017/12/15.
 */
public class Producer implements Runnable {
    private Resource res;

    public Producer(Resource res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true){
            res.set("+商品+");
        }
    }
}

定义消费者类

package com.ihujian.thread;

/**
 * Created by Administrator on 2017/12/15.
 */
public class Consumer implements Runnable {
    private Resource res;

    public Consumer(Resource res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true){
            res.out();
        }
    }
}

测试结果

package com.ihujian.thread;

/**
 * Created by Administrator on 2017/12/15.
 */
public class Demo3 {
    public static void main(String[] args) {
        Resource res = new Resource();
        new Thread(new Producer(res)).start();
        new Thread(new Consumer(res)).start();
    }
}

在这里如果是多个生产者和消费者,需要将两个方法的if改成while循环判断标记,并且讲notify()改成notifyAll()唤醒所有线程。 因为如果有多个生产者和消费者的话,使用notify()可能会唤醒己方线程,最终导致所有线程都等待

现在用jdk1.5的Lock接口来实现多消费者和多生产者的情景

定义资源类

package com.ihujian.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * jdk1.5提供了多线程的升级解决方案
 * 将同步synchronized替换成现实Lock操作
 * 将Object中的wait,notify,notifyAll替换了Condition对象,该对象可以通过Lock锁获取
 * Created by Administrator on 2017/12/15.
 */
public class Resource2 {
    private String name;
    private int count = 1;
    private boolean flag = false;
    private Lock lock = new ReentrantLock();
    private Condition condition_pro = lock.newCondition();
    private Condition condition_con = lock.newCondition();

    public void set(String name) throws InterruptedException {
        lock.lock();
        try {
            while (flag) {
                condition_pro.await();
            }
            this.name = name + "----" + count++;

            System.out.println(Thread.currentThread().getName() + "。。。生产者。。" + this.name);

            flag = true;
            condition_con.signal();
        }finally {

            lock.unlock();
        }
    }

    public void out() throws InterruptedException {
        lock.lock();
        try {

            while (!flag) {
                condition_con.await();
            }
            System.out.println(Thread.currentThread().getName() + "....消费者..." + this.name);
            flag = false;
            condition_pro.signal();
        }finally {
            lock.unlock();
        }
    }
}

生产者类

package com.ihujian.thread;

/**
 * Created by Administrator on 2017/12/15.
 */
public class Producer2 implements Runnable {
    private Resource2 res;

    public Producer2(Resource2 res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true){
            try {
                res.set("+商品+");
            } catch (InterruptedException e) {
            }
        }
    }
}

消费者类

package com.ihujian.thread;

/**
 * Created by Administrator on 2017/12/15.
 */
public class Consumer2 implements Runnable {
    private Resource2 res;

    public Consumer2(Resource2 res) {
        this.res = res;
    }

    @Override
    public void run() {
        while (true){
            try {
                res.out();
            } catch (InterruptedException e) {
            }
        }
    }
}

测试结果

package com.ihujian.thread;

/**
 * Created by Administrator on 2017/12/15.
 */
public class Demo4 {
    public static void main(String[] args) {
        Resource2 resource2 = new Resource2();

        new Thread(new Producer2(resource2)).start();
        new Thread(new Producer2(resource2)).start();
        new Thread(new Consumer2(resource2)).start();
        new Thread(new Consumer2(resource2)).start();
    }
}

相关文章

  • 生产者和消费者的Java实现方式

    引言 生产者与消费者问题是典型的多线程同步问题。生产者与消费者分别是两个角色,需要维护一个公共队列,生产者向队列中...

  • 多进程、多线程、生成器实现生产者消费者模型

    多线程实现 多线程实现生产者消费者模型的逻辑十分简单,生产者与消费者之间通过队列来进行通讯,所以生产者不用等待消费...

  • Java生产者和消费者实现

    0. 前言 生产者消费者是考察多线程的常见问题。最近尝试手写生产者和消费者时,发现这个问题并不止是考察多线程,还可...

  • wait/notify实现生产者消费者(6)

    生产者消费者模型 生产者消费者模型是一个典型的多线程问题,涉及生产者、消费者、产品仓库。生产者生产的产品放入仓库中...

  • 多线程并发之生产者消费者问题与读者写者问题

    多线程并发之生产者消费者问题与读者写者问题 引言 在程序界,有句流行语:我有一个问题,使用线程后,现在有了两个问题...

  • 生产者-消费者 模型

    生产者与消费者基本程序模型 在多线程开发过程之中最为著名的案例就是生产者与消费者操作,该操作的主要流程如下:生产者...

  • Java中生产者与消费者模式

    java生产者与消费者模式 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别...

  • 2019-04-24

    基于生产者与消费者的多线程Python实现 生产者生产,消费者消费,都是针对二者共同的钱包,生产者生产的钱放入钱包...

  • java多线程

    生产者与消费者问题

  • 操作系统知识点持续更新

    生产者消费者问题 关于生产者消费者问题可以参考这篇文章:生产者消费者问题的java实现 临界区与互斥量 临界区:保...

网友评论

      本文标题:多线程之生产者与消费者问题

      本文链接:https://www.haomeiwen.com/subject/snndwxtx.html