先看最简单的,也就是缓冲区的容量为1

缓冲区容量为1

import java.util.List;

public class ProducerAndConsumer2 {
    static class AddThread implements Runnable {
        Plate plate;

        public AddThread(Plate p) {
            this.plate = p;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            plate.put(new Object());
        }
    }

    static class GetThread implements Runnable {
        Plate plate;

        public GetThread(Plate p) {
            this.plate = p;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            plate.get();
        }
    }

    static class Plate {
        private List<Object> egg = new ArrayList<Object>();

        public synchronized void put(Object o) {
            while (egg.size() > 0) {
                try {
                    System.out.println(
                            "此时盘子里有鸡蛋    生产线程"+Thread.currentThread().getName()+"阻塞");
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            egg.add(0, o);
            System.out.println("生产线程放入一个鸡蛋");
            this.notifyAll();
        }

        public synchronized Object get() {
            while (egg.size() == 0) {
                try {
                    System.out.println(
                            "此时盘子里没有鸡蛋   消费线程"+Thread.currentThread().getName()+"阻塞");
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            Object object = egg.get(0);
            egg.clear();
            System.out.println("消费线程取得一个鸡蛋");
            this.notifyAll();
            return object;
        }
    }

    public static void main(String[] args) {
        Plate p = new Plate();
        for (int i = 0; i < 10; i++)
            new Thread(new GetThread(p)).start();

        for (int i = 0; i < 10; i++)
            new Thread(new AddThread(p)).start();
    }
}

如果盘子里可以存放多个鸡蛋就这样:

缓冲器容量大于1


import java.util.ArrayList;
import java.util.List;

public class ProducerAndConsumer {
    public static void main(String[] args) {
        Plate p = new Plate();

        for (int i = 0; i < 10; i++)
            new Thread(new GetThread(p)).start();
        for (int i = 0; i < 10; i++)
            new Thread(new AddThread(p)).start();
    }

}

class AddThread implements Runnable {
    Plate plate;

    public AddThread(Plate p) {
        this.plate = p;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        plate.put(new Object());
    }
}

class GetThread implements Runnable {
    Plate plate;

    public GetThread(Plate p) {
        this.plate = p;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        plate.get();
    }
}

class Plate {

    private List<Object> egg = new ArrayList<Object>(10);
                                   //在0-9这十个空间存储鸡蛋
    public synchronized void put(Object o) {
        while (egg.size()==10) { //最多有是个鸡蛋
            try {
                System.out.println(
                        "此时盘子里有鸡蛋    生产线程"+Thread.currentThread().getName()+"阻塞");
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        egg.add(o);
        System.out.println("生产线程放入一个鸡蛋 现有鸡蛋"+egg.size()+"个");
        this.notifyAll();
    }

    public synchronized Object get() {
        while (egg.size()==0) {
            try {
                System.out.println(
                        "此时盘子里没有鸡蛋   消费线程"+Thread.currentThread().getName()+"阻塞");
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        Object object=egg.get(egg.size()-1);
        egg.remove(egg.size()-1)
         this.notifyAll();
        System.out.println("消费线程取得一个鸡蛋  还剩余鸡蛋"+egg.size()+"个");
        return object;
    }

}

关于线程通信还有一个似乎是空中网的面试题

地址如下

http://blog.csdn.net/dlf123321/article/details/42751405

感谢glt

参考资料

http://blog.csdn.net/ghsau/article/details/7433673

http://blog.csdn.net/monkey_d_meng/article/details/6251879

生产者消费者的java实现的更多相关文章

  1. 生产者消费者问题Java三种实现

    生产者-消费者Java实现 2017-07-27 1 概述 生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品. 解决生产者/ ...

  2. 生产者消费者模式-Java实现

    感知阶段 随着软件业的发展,互联网用户的日渐增多,并发这门艺术的兴起似乎是那么合情合理.每日PV十多亿的淘宝,处理并发的手段可谓是业界一流.用户访问淘宝首页的平均等待时间只有区区几秒,但是服务器所处理 ...

  3. 生产者消费者模型Java实现

    生产者消费者模型 生产者消费者模型可以描述为: ①生产者持续生产,直到仓库放满产品,则停止生产进入等待状态:仓库不满后继续生产: ②消费者持续消费,直到仓库空,则停止消费进入等待状态:仓库不空后,继续 ...

  4. 生产者消费者模型java

    马士兵老师的生产者消费者模型,我感觉理解了生产者消费者模型,基本懂了一半多线程. public class ProducerConsumer { public static void main(Str ...

  5. 生产者消费者模型-Java代码实现

    什么是生产者-消费者模式 比如有两个进程A和B,它们共享一个固定大小的缓冲区,A进程产生数据放入缓冲区,B进程从缓冲区中取出数据进行计算,那么这里其实就是一个生产者和消费者的模式,A相当于生产者,B相 ...

  6. JAVA多线程之生产者 消费者模式 妈妈做面包案例

    创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包  最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...

  7. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  8. Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)

    生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ...

  9. Java数据结构之队列的实现以及队列的应用之----简单生产者消费者应用

    Java数据结构之---Queue队列 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在 ...

随机推荐

  1. 浅析深度学习mini_batch的BP反传算法

    在深度学习中,如果我们已经定义了网络,输入,以及输出,那么接下来就是损失函数,优化策略,以及一般由框架完成的BP反传.这篇博文我们主要探讨一下深度的BP反传算法(以梯度下降为例),尤其是mini_ba ...

  2. WebView 的使用案例

    package com.example.day20_webview; import android.os.Bundle; import android.annotation.SuppressLint; ...

  3. Android在一个TextView里显示不同样式的字体

    在同一个TextView里显示不同样式的字体 public void setSpan(Object what, int start, int end, int flags); 样式1:背景色.粗体.字 ...

  4. 4.0、Android Studio配置你的构建

    Android构建系统编译你的app资源和源码并且打包到APK中,你可以用来测试,部署,签名和发布.Android Studio使用Gradle,一个高级的构建套件,来自动化和管理构建进程,同时可以允 ...

  5. Hibernate系列学习之(二) 多对一、一对一、一对多、多对多的配置方法

    这是近期做案件录入.java项目中体会的几点:项目理解很是深刻,和大家共勉! hihernate一对多关联映射(单向Classes----->Student) 一对多关联映射利用了多对一关联映射 ...

  6. Android平移动画

    Android平移动画 核心方法 public void startAnimation(Animation animation) 执行动画,参数可以是各种动画的对象,Animation的多态,也可以是 ...

  7. 登录ssh时Host key verification failed错误

    工作中总是测试不同的路由设备, 路由器的ip都是 192.168.111.1 ,ssh登录的时候总是出现这个错误. macos上,错误如下 spawn ssh -p 22 root@192.168.1 ...

  8. Android之Notification-android学习之旅(二)

    notification常用于下拉式的消息推送. Notification的构成 Nitification的实例 1.新建一个Builder,要选Notification.compat包. 2.然后用 ...

  9. springMVC源码分析--容器初始化(一)ContextLoaderListener

    在spring Web中,需要初始化IOC容器,用于存放我们注入的各种对象.当tomcat启动时首先会初始化一个web对应的IOC容器,用于初始化和注入各种我们在web运行过程中需要的对象.当tomc ...

  10. SDL2源代码分析8:视频显示总结

    ===================================================== SDL源代码分析系列文章列表: SDL2源代码分析1:初始化(SDL_Init()) SDL ...