博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程模拟实现生产者/消费者模型 (借鉴)
阅读量:6201 次
发布时间:2019-06-21

本文共 3493 字,大约阅读时间需要 11 分钟。

 在生产者/消费者模型中,生产者Producer负责生产数据,而消费者Consumer负责使用数据。多个生产者线程会在同一时间运行,生产数据,并放到内存中一个共享的区域。期间,多个消费者线程读取内存共享区,消费里面的数据。

分析

在下面Java应用程序中,生产者线程向一个线程安全的堆栈缓冲区中写(PUSH)数据,消费者从该堆栈缓冲区中读(POP)数据,这样,这个程序中同时运行的两个线程共享同一个堆栈缓冲区资源。

类Producer是生产者模型,其中的run方法中定义了生产者线程所做的操作,循环调用push()方法,将生产的100个字母送入堆栈中,每次执行完push操作后,调用sleep方法睡眠一段随机时间。

类Consumer是消费者模型,循环调用pop方法,从堆栈取出一个字母,一共取100次,每次执行完push操作后,调用sleep方法睡眠一段随机时间

同步堆栈类SynchronizedStack

package com.ailk.biapp.ci.ProducerAndConsumer;public class SynchronizedStack {    private int index = 0;    private int size = 100;    //共享内存区    private char[] data;        public SynchronizedStack(int size){        System.out.println("栈被创建");        this.size = size;        data = new char[size];    }         /**     * 生产数据     *      * @param c     */    public synchronized void push(char c){        while (index == size){            try{                System.err.println("生产数据满了");                this.wait();//等待,直到有数据出栈            }catch(InterruptedException e){                 Thread.currentThread().interrupt();                 e.printStackTrace();            }        }        data[index] = c;        index++;        this.notify();//通知其他线程把数据出栈     }        /**     * 消费数据     *      * @return     */    public synchronized char pop(){        while (index == 0){            try{                System.err.println("栈空了");                this.wait();// 等待,直到有数据出栈            }catch(InterruptedException e){                Thread.currentThread().interrupt();                e.printStackTrace();            }        }        index --;//指针向下移动        char ch = data[index];        this.notify();//通知其他线程把数据入栈        return ch;    }        //显示堆栈内容    public synchronized void print(){        for(int i = 0; i < data.length; i++){            System.out.println(data[i]);        }        System.out.println();        this.notify();// 通知其它线程显示堆栈内容    }    }

生产者Product

package com.ailk.biapp.ci.ProducerAndConsumer;public class Producer implements Runnable{    private SynchronizedStack stack;        public Producer(SynchronizedStack s){        stack = s;    }        public void run(){        char ch;        for(int i = 0; i< 100; i++){            //随机产生100个字符            ch = (char) (Math.random() * 26 + 'A');            stack.push(ch);            System.out.println("Produced:" + ch);            try{                //每一个字符线程就休眠一下                 Thread.sleep((int) (Math.random() * 1000));            }catch (InterruptedException e) {        }    }    }}

消费者Consumer

package com.ailk.biapp.ci.ProducerAndConsumer;public class Consumer implements Runnable{    private SynchronizedStack stack;        public Consumer(SynchronizedStack s){        stack = s;    }        public void run() {        char ch;        for(int i = 0 ; i < 100; i++){            ch = stack.pop();            System.out.println("Consumed:" + ch);        }        try{             Thread.sleep((int) (Math.random() * 1000));        }catch(InterruptedException e){                    }            }}

测试:

package com.ailk.biapp.ci.ProducerAndConsumer;public class ProductConsumerTest {    public static void main(String args[]){        // 下面的消费者类对象和生产者类对象所操作的是同一个同步堆栈对象        SynchronizedStack stack = new SynchronizedStack(5);        Runnable source = new Producer(stack);        Runnable sink = new Consumer(stack);        Thread t1 = new Thread(source);        Thread t2 = new Thread(sink);        t1.start();        t2.start();    }}

借鉴于:http://www.cnblogs.com/linjiqin/archive/2011/04/15/2016820.html

你可能感兴趣的文章
输入两个很大的正数(用C字符串表示),输出他们的乘积,将设不考虑非法输入。...
查看>>
从零开始学习 asp.net core 2.1 web api 后端api基础框架(一)-环境介绍
查看>>
vue vm.$attrs 使用
查看>>
Spring Boot:内置tomcat启动和外部tomcat部署总结
查看>>
Intellij IDEA快捷键
查看>>
Java 8 forEach简单例子
查看>>
Entity Framework Core 2.1,添加种子数据
查看>>
JAVA实现长连接(含心跳检测)Demo
查看>>
记录一则expdp任务异常处理案例
查看>>
[转]Illuminate Database
查看>>
echarts的地图点击事件
查看>>
C# 在PPT中绘制形状(shape)
查看>>
初探APT攻击
查看>>
Spring的Task任务
查看>>
ClassLoader家族
查看>>
C# 多线程九之Timer类
查看>>
spring注解@Scheduled中fixedDelay、fixedRate和cron表达式的区别
查看>>
centos 修改主机名
查看>>
Java访问子类对象的实例变量
查看>>
About Realtime Radiosity
查看>>