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. 搭建vue项目环境

    前言 在开发本项目之前,我对vue,react,angular等框架了解,仅限于知道它们是什么框架,他们的核心是什么,但是并没有实际使用过(angular 1.0版本用过,因为太难用,所以对这类框架都 ...

  2. Session 和 Cookie 区别

    会话跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.==Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用 ...

  3. Stanford依存句法关系解释

    ROOT:要处理文本的语句 IP:简单从句 NP:名词短语 VP:动词短语 PU:断句符,通常是句号.问号.感叹号等标点符号 LCP:方位词短语 PP:介词短语 CP:由'的'构成的表示修饰性关系的短 ...

  4. leetcode算法: Average of Levels in Binary Tree

    Given a non-empty binary tree, return the average value of the nodes on each level in the form of an ...

  5. Android fragment切换后onresume时报 Attempt to write to field 'int android.support.v4.app.Fragment.mNextAnim'

    动态加载fragment以后,调用了remove方法移除Fragment,在返回来的时候报 Attempt to write to field 'int android.support.v4.app. ...

  6. python/ Django之中间件

    python/ Django之中间件 一.中间件 中间件共分为: (1)process_request(self,request) (2)process_view(self, request, cal ...

  7. flask +gevent+nginx+Gunicorn+supervisor部署flask应用

    上篇   可以完美部署flask ,但是视乎在结合gevent+apscheduler 实现异步非阻塞后台和定时任务的时候视乎不是那么完美.请教了前辈,决定使用flask+gevent+nginx+g ...

  8. Java基础语法<四> 控制流程

    笔记整理 来源于<Java核心技术卷 I > <Java编程思想>   if while do while for   switch case case标签可以是: 类型为ch ...

  9. XPath 轴

    XML 实例文档 我们将在下面的例子中使用此 XML 文档: <?xml version="1.0" encoding="ISO-8859-1"?> ...

  10. Spring(3)——装配 Spring Bean 详解

    装配 Bean 的概述 前面已经介绍了 Spring IoC 的理念和设计,这一篇文章将介绍的是如何将自己开发的 Bean 装配到 Spring IoC 容器中. 大部分场景下,我们都会使用 Appl ...