多线程案例:生产者和消费者

多线程案例:生产者和消费者

 1.生产和消费的产品抽象类:


public abstract class Product {

    public String name;
    public abstract String toString();
}

2.一个具体的产品类:

public class AProduct extends Product {

    public AProduct(String name) {

        this.name = name;
        // TODO Auto-generated constructor stub
    }
    public String toString() {

        // TODO Auto-generated method stub
        return this.name;
    }
}

3.容器类(仓库):

import java.util.ArrayList;

/*
 * 存放生产者和消费者的产品队列
 * */

public class Container {

    private ArrayList arrList = new ArrayList();
    private int LENGTH = 10;
    public boolean isFull() {

        return arrList.size()==LENGTH;
    }
    public boolean isEmpty() {

        return arrList.isEmpty();
    }

    /* 如果此处不加synchronized锁,那么也可以再调用push的地方加锁
    * 既然此处加了锁,那么再别的地方可以不加锁
    */

    public synchronized void push(Object o) {

        arrList.add(o);
    }
    // 如果此处不加synchronized锁,那么也可以再调用push的地方加锁
    public synchronized Object pop() {

        Object lastOne = arrList.get(arrList.size()- 1);
        arrList.remove(arrList.size()- 1);
        return lastOne;
    }
}

4.休息一会,生产者和消费者都要休息,因此作为抽象基类:

public abstract class Sleep {

    public void haveASleep() throws InterruptedException {

        Thread.sleep((long)(Math.random()* 3000));
    }
}

/*
 * 消费者线程
 * */

public class Consumer extends Sleep implements Runnable {

    private Container contain =null;
    public Consumer(Container contain) {

        this.contain = contain;
    }
    public void run() {

        // TODO Auto-generated method stub
        while(true) {

            synchronized(contain) {

                while(contain.isEmpty()) {

                    try{

                        contain.wait();
                    }catch(InterruptedException e) {

                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            consume();//消费
            try {

                haveASleep();
            }catch(InterruptedException e) {

                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized(contain) {

                contain.notify();
            }
        }
    }
    private void consume() {

        Product a = (AProduct)contain.pop();
        System.out.println("消费了一个产品"+ a.toString());
    }
}

/*
 * 生产者线程
 * */

public class Producator extends Sleep implements Runnable {

    private Container contain = null;
    public Producator(Container contain) {

        super();
        this.contain = contain;
    }
    public void run() {

        // TODO Auto-generated method stub
        while(true) {

            synchronized(contain) {

                while(contain.isFull()) {

                    try{

                        contain.wait();// 阻塞当前线程,当前线程进入等待队列。这个时候只有等待别的线程来唤醒自己了。
                    }catch(InterruptedException e) {

                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            producer();// 生产一个产品
            try {

                haveASleep();
            }catch(InterruptedException e) {

                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized(contain) {

                contain.notify();// 唤醒等待队列中正在等待的第一个线程,让其执行。
            }
        }
    }
    public void producer() {

        Product aProduct = new AProduct("pp:"+String.valueOf((int)(10*Math.random())));
        System.out.println("生产了一个产品:"+ aProduct.toString());
        contain.push(aProduct);
    }
}

5. 写一个测试:

public class TestMain {

    /**
     * @param args
     */

    public static void main(String[] args) {

        // TODO Auto-generated method stub
        Container contain = new Container();
        Producator p = new Producator(contain);
        Consumer c = new Consumer(contain);
        Thread pt =new Thread(p);
        Thread ct =new Thread(c);
        pt.start();
        ct.start();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100530.html原文链接:https://javaforall.net

(0)
上一篇 2021年5月6日 下午2:00
下一篇 2021年5月6日 下午3:00


相关推荐

  • 2026全网最全“养虾”指南:阿里、腾讯、字节本地版 Open Claw 深度测评

    2026全网最全“养虾”指南:阿里、腾讯、字节本地版 Open Claw 深度测评

    2026年3月14日
    2
  • git学习——设置gitlab、github默认push的用户名和密码

    在使用git的时候,不同的环境下,当你重新安装git,最好在开始的时候就配置一下默认的git的用户名和密码,这样子就可以在每次的push的时候不需要手动的在去输入git的用户名和密码,提高执行的效率。 环境:Windows环境已经安装git,我使用的gitlab(github和这样配一样),gitlab的用户名742981086@qq.com 下面在Windows环境中进行配置过程的演示, 1

    2022年2月25日
    325
  • 软件测试等价类划分实例_软件测试原则

    软件测试等价类划分实例_软件测试原则等价类的设计思路:根据输入条件,确定等价类,包括有效等价类和无效等价类,建立等价类列表为每个等价类规定一个唯一的编号设计一个测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类被覆盖完为止设计一个测试用例,使其尽可能多的覆盖尚未被覆盖的无效等价类,重复这一步,直到所有的无效等价类被覆盖完为止1、三角形–等价类测试的例子某程序规定:"输入三个整数 a 、 b 、 c…

    2022年8月31日
    8
  • 论文摘抄 – FlumeJava[通俗易懂]

    论文摘抄 – FlumeJava

    2022年2月1日
    42
  • python traceback_Python语言Traceback详解

    python traceback_Python语言Traceback详解本文主要向大家介绍了 Python 语言 Traceback 详解 通过具体的内容向大家展示 希望对大家学习 Python 语言有所帮助 刚接触 Python 的时候 简单的异常处理已经可以帮助我们解决大多数问题 但是随着逐渐地深入 我们会发现有很多情况下简单的异常处理已经无法解决问题了 如下代码 单纯的打印异常所能提供的信息会非常有限 deffunc1 raiseExcepti func1e

    2026年3月16日
    3
  • anaconda3如何卸载干净「建议收藏」

    anaconda3如何卸载干净「建议收藏」最近跑代码的时候老出现各种错误,因为之前卸载过一次anaconda,所以猜测可能是没有卸载干净,所以又重新卸载了一遍,为了防止再次出现卸载不干净的情况,找了很久,终于从官网上找到了能够卸载干净的方法。安装Anaconda-Cleanpackage 打开AnacondaPrompt,输入命令行: condainstallanaconda-clean 接着输入命令行进行卸载…

    2022年6月29日
    299

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号