package com.wenki.thread;

import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProductAndConsume {

    public static void main(String[] args) {
        ProductAndConsume o = new ProductAndConsume();
//        Storage storage = o.new StorageOne();
//        Storage storage = o.new StorageTwo();
        Storage storage = o.new StorageThree();
        Consumer consumer1 = o.new Consumer(storage);
        Consumer consumer2 = o.new Consumer(storage);
        Producter producter1 = o.new Producter(storage);
        Producter producter2 = o.new Producter(storage);
        Producter producter3 = o.new Producter(storage);
        consumer1.start();
        consumer2.start();
        producter1.start();
        producter2.start();
        producter3.start();
    }

    class Producter extends Thread{
        Storage storage;
        public Producter(Storage storage) {
            this.storage = storage;
        }
        public void product(){
            this.storage.product();
        }
        @Override
        public void run() {
            for(;;){
                product();
            }
        }
    }

    class Consumer extends Thread{
        Storage storage;
        public Consumer(Storage storage){
            this.storage = storage;
        }
        public void consume(){
            this.storage.consume();
        }
        @Override
        public void run() {
            for(;;){
                consume();
            }
        }
    }

    interface Storage{
        int MAX_SIZE = 100;
        LinkedList<Object> list = new LinkedList<Object>();
        public abstract void product();
        public abstract void consume();
    }

    //第一种方式  wait() + notify()
    class StorageOne implements Storage{

        @Override
        public void product() {
            synchronized (list) {
                while(list.size() == MAX_SIZE){
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(list.add(new Object())){
                    System.out.println("生产 ### 产品数量 : " + list.size());
                    //通知消费者可以继续消费
                    list.notifyAll();
                }
                try {
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void consume() {
            synchronized (list) {
                while(list.size() == 0){
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(list.remove() != null){
                    System.out.println("消费 ### 产品数量: " + list.size());
                    //通知生产者可以继续生产
                    list.notifyAll();
                }
                try {
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

    //第二种方式 await() + signal()
    class StorageTwo implements Storage{

        Lock lock = new ReentrantLock();
        Condition fully = lock.newCondition();
        Condition empty = lock.newCondition();

        @Override
        public void product() {
            lock.lock();
            try{
                while(list.size() == MAX_SIZE){
                    fully.await();
                }
                if(list.add(new Object())){
                    System.out.println("生产 ### 产品数量 : " + list.size());
                    empty.signalAll();
                }
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }

        }

        @Override
        public void consume() {
            lock.lock();
            try{
                while(list.size() == 0){
                    empty.await();
                }
                if(list.remove() != null){
                    System.out.println("消费 ### 产品数量: " + list.size());
                    fully.signalAll();
                }
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        }

    }

    //第三种 BlockingQueue 阻塞队列
    class StorageThree implements Storage{

        LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<Object>(MAX_SIZE);

        @Override
        public void product() {
            try {
                list.put(new Object());
                System.out.println("生产 ### 产品数量 : " + list.size());
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        @Override
        public void consume() {
            try {
                if(list.take() != null){
                    System.out.println("消费 ### 产品数量: " + list.size());
                }
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

java实现生产者/消费者的三种方式的更多相关文章

  1. java 实现md5加密的三种方式与解密

      java 实现md5加密的三种方式 CreateTime--2018年5月31日15点04分 Author:Marydon 一.解密 说明:截止文章发布,Java没有实现解密,但是已有网站可以免费 ...

  2. java中遍历集合的三种方式

    第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ...

  3. java加载配置文件的三种方式

    比如我们要加载db.properties文件 如图: 比如我们要加载source目录下的db.properties文件.就有以下几种方式 第一种是文件io流: public static void l ...

  4. JAVA实现Base64编码的三种方式

    摘要: Javabase64编码的三种方式   有如下三种方式: 方式一:commons-codec.jar Java代码  1. String base64String="whuang12 ...

  5. Java通过JDBC连接数据库的三种方式!!!并对数据库实现增删改查

    前言 java连接数据库完整流程为: 1,获得驱动(driver),数据库连接(url),用户名(username),密码(password)基本信息的三种方式. 2,通过获得的信息完成JDBC实现连 ...

  6. java实现HTTP请求的三种方式

    目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...

  7. 【转载】java实现HTTP请求的三种方式

    目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...

  8. Java 实现线程安全的三种方式

    一个程序在运行起来的时候会转换成进程,通常含有多个线程. 通常情况下,一个进程中的比较耗时的操作(如长循环.文件上传下载.网络资源获取等),往往会采用多线程来解决. 比如显示生活中,银行取钱问题.火车 ...

  9. HTTP:Java实现HTTP请求的三种方式

    目前JAVA实现HTTP请求的方法用的最多的有两种: 一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,H ...

随机推荐

  1. 清华集训2015 V

    #164. [清华集训2015]V http://uoj.ac/problem/164 统计 描述 提交 自定义测试 Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化题目,题目中的常数 ...

  2. zookeeper入门系列:paxos协议

    上一章讨论了一种强一致性的情况,即需要分布式事务来解决,本章我们来讨论一种最终一致的算法,paxos算法. paxos算法是由大牛lamport发明的,关于paxos算法有很多趣事.比如lamport ...

  3. Centos7 Yum方式安装Mysql7

    不废话,直奔主题,可以覆盖安装. 下载并安装MySQL官方的 Yum Repository [root@localhost ~]# wget -i -c http://dev.mysql.com/ge ...

  4. php析构方法

    析构方法说明: 1. 析构方法会自动调用 2. 析构方法主要用于销毁资源(比如释放数据库的链接,图片资源...销毁某个对象..); 析构函数会在到对象的所有的引用都被删除或者当对象被显示销毁时执行. ...

  5. 什么是KMP算法?KMP算法推导

    花了大概3天时间,了解,理解,推理KMP算法,这里做一次总结!希望能给看到的人带来帮助!! 1.什么是KMP算法? 在主串Str中查找模式串Pattern的方法中,有一种方式叫KMP算法 KMP算法是 ...

  6. java的<<左移,>>右移,>>>无符号右移

    >>右移 右移,道在二进制中,假设用一个32位的Int表示一个64,那么高位就都是0,所以当我们把整个二进制数右移,如0100000 >> 2 = 0001000,可以看到右移 ...

  7. Struts2 之值栈

    值栈(ValueStack) http://www.cnblogs.com/bgzyy/p/8639893.html 这是我的有关 struts2 的第一篇文章,对于里面我们说到的一个 struts2 ...

  8. centos7.0下的 systemctl 用法

    参考链接: http://man.linuxde.net/systemctl

  9. CNN中减少网络的参数的三个思想

    CNN中减少网络的参数的三个思想: 1) 局部连接(Local Connectivity) 2) 权值共享(Shared Weights) 3) 池化(Pooling) 局部连接 局部连接是相对于全连 ...

  10. python json.dumps 中的ensure_ascii 参数引起的中文编码问题

    在使用json.dumps时要注意一个问题   >>> import json >>> print json.dumps('中国') "\u4e2d\u5 ...