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

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

 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年10月1日
  • 浏览器被hao.360.cn劫持怎么办

    浏览器被hao.360.cn劫持怎么办特么的现在互联网太没节操了,一大早发现我的浏览器被hao.360.cn劫持了,弄了好久都没弄好,后来一想可能是因为qvod的原因,这可是哥当年看片的神器啊……废话不说:1,进入:C:\ProgramData\QvodPlayer\QvodWebBase2,点开1.0.0.53(或者其它)文件夹3,直接删除里面的文件是删除不了的。更改QvodWebBase64.dll后缀名为QvodWebB…

    2022年7月14日
  • CTFshow——SSTI

    CTFshow——SSTI首先一定要了解有关python类的知识:python__base__等内置方法pythoninspect模块解析#coding=utf-8__author__=”leaves”classBase(object):a=0def__init__(self):self._a=10passclassChild(Base):”测试测试”_b=10def__str__(

    2022年10月20日
  • 用批处理文件阻止win10强制更新

    用批处理文件阻止win10强制更新win10这个商业巨头微软的最新之作,以流氓行径著称,尤其是它的自动更新最受诟病。用户无权选择是否下载和安装更新。你选择不更新,他就在后台下载,下次开机自动安装。何况,这些更新有的没必要,有的装上反而起副作用。我之前就被装上的更新弄坏网卡驱动,重装一次系统;今年3月大范围爆发的更新bug,导致众多用户USB驱动坏掉,又重装一次系统。再后来,我知道了更新的危害,就每天手动删除那些更新安装包,结果有一…

    2022年6月4日
  • CMake Error: The current CMakeCache.txt directory is different…[通俗易懂]

    CMake Error: The current CMakeCache.txt directory is different…[通俗易懂]零、问题描述开始学ROS时,需要编译别人的功能包,常常把别人的工作空间拿过来使用,但编译时会出现各种错误,如下的目录问题:CMakeError:ThecurrentCMakeCache.txtdirectory/home/vistar/desktop/catkin_ws/build/CMakeCache.txtisdifferentthanthedirectory/ho……………

    2022年10月25日
  • ubuntu开机进入tty1_ubuntu tty模式

    ubuntu开机进入tty1_ubuntu tty模式1、一个作为宿主机的Linux;本文使用的是RedhatEnterpriseLinux5.4;2、在宿主机上提供一块额外的硬盘作为新系统的存储盘,为了降低复杂度,这里添加使用一块IDE接口的新硬盘;3、Linux内核源码,busybox源码;本文使用的是目前最新版的linux-2.6.34.1和busybox-1.16.1。说明:本文是一个stepbystep的…

    2022年8月12日

发表回复

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

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