- 浏览: 123917 次
- 性别:
- 来自: 抽象空间
最新评论
-
Dancen:
理想状态下jar包的更新当然不应该去修改其中的方法签名等外部依 ...
javamake.jar & javamake-ant15.jar -
mwei:
Dancen 写道javamake可以解决代码之间的依赖问题, ...
javamake.jar & javamake-ant15.jar -
Dancen:
javamake可以解决代码之间的依赖问题,但如果调用的是外部 ...
javamake.jar & javamake-ant15.jar -
kidding87:
看到了楼主的connet by用法,又看到这个很久以前的东西, ...
海螺式初始化二维数组 -
pxlfxl2:
mwei 写道pxlfxl2 写道如果我的需求是要打印A到Z ...
三线程顺序打印N次ABC
关于Object.wait()和Object.notify()/notifyAll()的使用,再写个练习。
生产者-消费者问题:有一个公共的资源池Source,生产者生产物品放到资源池中,消费者从资源池拿物品消费掉。
当资源池没有资源(物品)的时候,通知生产者生产物品放到资源池里;
当任何一个生产者生产完成之后,通知消费者们来消费物品;
消费者们会把所有资源消费掉,然后通知生产者生产物品;
啰嗦这么多,就是生产的时候只能有一个生产者,不能两个(多个)生产者连续生产;消费的时候可以有多个消费者连续消费。
就用这样的需求练习练习吧。
假设资源池Source是个长度为30的数组int[] source=new int[30]; //值[1,2,3...,28,29,30] 数组的值=相应下标+1;
数组的值只是用于标记,标记这个位置已经放置物品了;
第一次生产了20个物品,那么放置的位置是数组的下标[0,19],相应值是[1,20];
那么下次(可能是别的生产者)放置物品的开始位置(下标)是20;
通知消费者们来消费,那么消费者消费的开始位置(下标)是0;
消费完之后,如果第二次也生产了20个物品,那么放置的位置是数组的下标[20,9],相应值是[21,22..29,30,1,2...9,10];
那么下次(可能是别的生产者)放置物品的开始位置(下标)是10;通知消费者们来消费,那么消费者消费的开始位置(下标)是20;
此时把资源池想象成为一个可旋转的大圆桌,在圆桌的边缘放置了30个碟子,编号就是0到29;
通过向固定的方向旋转圆桌来有秩序的生产和消费^..^
还请JE上的朋友给点建议。
资源池类:
生产者类:
消费者类
测试:
运行结果的一部分:
生产者-消费者问题:有一个公共的资源池Source,生产者生产物品放到资源池中,消费者从资源池拿物品消费掉。
当资源池没有资源(物品)的时候,通知生产者生产物品放到资源池里;
当任何一个生产者生产完成之后,通知消费者们来消费物品;
消费者们会把所有资源消费掉,然后通知生产者生产物品;
啰嗦这么多,就是生产的时候只能有一个生产者,不能两个(多个)生产者连续生产;消费的时候可以有多个消费者连续消费。
就用这样的需求练习练习吧。
假设资源池Source是个长度为30的数组int[] source=new int[30]; //值[1,2,3...,28,29,30] 数组的值=相应下标+1;
数组的值只是用于标记,标记这个位置已经放置物品了;
第一次生产了20个物品,那么放置的位置是数组的下标[0,19],相应值是[1,20];
那么下次(可能是别的生产者)放置物品的开始位置(下标)是20;
通知消费者们来消费,那么消费者消费的开始位置(下标)是0;
消费完之后,如果第二次也生产了20个物品,那么放置的位置是数组的下标[20,9],相应值是[21,22..29,30,1,2...9,10];
那么下次(可能是别的生产者)放置物品的开始位置(下标)是10;通知消费者们来消费,那么消费者消费的开始位置(下标)是20;
此时把资源池想象成为一个可旋转的大圆桌,在圆桌的边缘放置了30个碟子,编号就是0到29;
通过向固定的方向旋转圆桌来有秩序的生产和消费^..^
还请JE上的朋友给点建议。
资源池类:
/** * 资源池 * @author mwei * @version 1.0 */ public class Source { public static final int CAPACITY=30; public static int[] source=new int[CAPACITY]; //值[1,2,3...,28,29,30] public static int in=0; //the position to set source public static int out=0; //the position to get source public static final byte[] LOCK=new byte[0]; }
生产者类:
import java.util.Random; public class Producer implements Runnable{ public static Random random=new Random(); public static volatile boolean prun=true; //信号量 private String name; public Producer(String name){this.name=name;} public String getName(){return name;} public void run(){produce();} public void produce(){ while (true) { synchronized (Source.LOCK) { if (prun) { Source.LOCK.notifyAll(); int planNum = random.nextInt(10) + 15; // 计划生产资源的数量,最少15个,最多24个 int actualNum = 0; for (int i = Source.out; i < Source.CAPACITY + Source.out; i++) { // 查找放置资源的位置 int index = i % Source.CAPACITY; if (Source.source[index] == 0) { Source.in = index; // 找到 break; } } for (int i = 0; i < planNum; i++) { // 放置资源 if (Source.source[Source.in] == 0) { actualNum++; // 统计实际放置资源的个数 Source.source[Source.in] = Source.in + 1; Source.in = (++Source.in % Source.CAPACITY); } } int total = 0; for (int i = 0; i < Source.CAPACITY; i++) { // 统计资源池中总共的资源个数 if (Source.source[i] != 0) total++; } System.out.print(this.getName() + "Plan : " + planNum + "\t Produce : " + actualNum); // 输出计划量和实际生产量 System.out.println("\tTotal : " + total + "\tRange : [" + Source.out + "," + (Source.in + Source.CAPACITY - 1) % Source.CAPACITY + "]"); // 资源总值及范围 prun = false; // 生产者只生产一次 Consumer.crun = true; } else { try { System.out.println(this.getName() + ".wait();"); Source.LOCK.wait(); } catch (InterruptedException ie) { ie.printStackTrace(); } } } // end syn } // end while } }
消费者类
public class Consumer implements Runnable{ public static final int CONSUME_NUM=4; public static volatile boolean crun=false; //信号量 private String name; public Consumer(String name){ this.name=name; } public String getName(){ return name; } public void run(){ consume(); } public void consume(){ while (true) { synchronized (Source.LOCK) { if (crun) { Source.LOCK.notifyAll(); int actualNum = 0; for (int i = 0; i < CONSUME_NUM; i++) { if (Source.source[Source.out] != 0) { actualNum++; Source.source[Source.out] = 0; // 消耗掉 Source.out = (Source.out + 1) % Source.CAPACITY; } else { ; // do nothing } } System.out.println(this.getName() + " : consumes " + actualNum); int total = 0; for (int i = 0; i < Source.CAPACITY; i++) { // 统计资源池中总共的资源个数 if (Source.source[i] != 0) total++; } if (total == 0) { // 消费者把资源消费光了再通知生产者 crun = false; Producer.prun = true; } } else { try { System.out.println(this.getName() + ".wait();"); Source.LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } // end syn } // end while } }
测试:
/** * test 3 producers and 4 consumers * @author mwei */ public class Test { public static void main(String[] args) { new Thread(new Producer("P1=>")).start(); new Thread(new Producer("P2=>")).start(); new Thread(new Producer("P3=>")).start(); new Thread(new Consumer("C1=>")).start(); new Thread(new Consumer("C2=>")).start(); new Thread(new Consumer("C3=>")).start(); new Thread(new Consumer("C4=>")).start(); } }
运行结果的一部分:
P3=>Plan : 18 Produce : 18 Total : 18 Range : [28,15] C2=> : consumes 4 C3=> : consumes 4 C1=> : consumes 4 C4=> : consumes 4 P3=>.wait(); C2=> : consumes 2 P2=>Plan : 19 Produce : 19 Total : 19 Range : [16,4] C3=> : consumes 4 C1=> : consumes 4 C4=> : consumes 4 C2=> : consumes 4 P2=>.wait(); C3=> : consumes 3 C1=>.wait(); C4=>.wait(); C2=>.wait(); C3=>.wait(); P3=>Plan : 18 Produce : 18 Total : 18 Range : [5,22] P1=>.wait(); P2=>.wait(); C3=> : consumes 4 C1=> : consumes 4 P3=>.wait(); C4=> : consumes 4 C2=> : consumes 4 C3=> : consumes 2 C1=>.wait(); C4=>.wait(); C2=>.wait(); C3=>.wait(); P2=>Plan : 18 Produce : 18 Total : 18 Range : [23,10] P1=>.wait(); P3=>.wait(); P2=>.wait(); C1=> : consumes 4 C4=> : consumes 4 C3=> : consumes 4 C2=> : consumes 4 C1=> : consumes 2 C4=>.wait(); C3=>.wait(); C2=>.wait();
发表评论
-
泛型<T>的转换问题
2011-04-28 15:03 2在问答里提问,没有得到答案,特开此贴讨论。 代码如下: ... -
fibonacci的几种实现及尾递归
2011-03-27 22:55 3838/** * java version "1. ... -
将一个自然数拆分为若干不重复自然数之和(OO实现)
2011-03-13 22:04 2133原题出处:http://www.iteye ... -
自然数m的立方可写成m个连续奇数之和
2010-10-22 09:49 4480题目: 任何一个自然数m的立方均可写成m个连续奇数之和。 例如 ... -
使用内部类实现多重继承
2010-09-07 19:10 1147最常见的实现多重继承的方式,是implements inter ... -
怎么捕获webwork下载文件时的异常
2010-08-09 17:02 1046使用webwork的文件下载方式,action配置如下: ... -
java.rmi.UnmarshalException: invalid method hash
2010-07-30 16:25 4113今天在应用程序中报了下面异常: java.rmi.Serv ... -
转:java 获取ftp文件大小
2010-07-30 11:46 9892【注】:本代码摘自 http://www.java2s.com ... -
判断字符串是否是数字
2010-03-13 14:47 1072看到一笔试题,如题; 《c程序设计语言》第二版5.2节里有ge ... -
三线程顺序打印N次ABC
2010-02-27 15:17 3076记得前一阵子JE上讨论线程顺序打印的面试题,现在有空也练练。 ... -
求数组的平衡点
2010-02-27 14:47 2083原文见:http://www.iteye.com/topic/ ... -
怎么记忆Thread.join()
2010-02-23 16:57 2610Thread.join() JDK_API:等待该线程终止。 ... -
海螺式初始化二维数组
2009-12-13 22:33 1472原题见:http://www.iteye.com/topic/ ... -
初涉java多线程(二)
2009-12-04 23:10 977原文:http://huagenli.iteye.com/bl ... -
Collection’modifiers seem not correct when reflect
2009-12-03 22:48 1029做练习的时候就抄了如下方法 public static v ... -
对private static 实例变量同步,线程获得的是什么锁?
2009-11-29 11:01 1181初学线程,还是比较愚的。 问题如题,就是在方法中加了synch ... -
初涉java多线程(一)
2009-11-23 22:14 935十一期间看了一点java多 ... -
new StringBuilder() VS new StringBuilder(arg)
2009-09-30 17:35 1339StringBuilder,非线程安全 ... -
一种截取字母汉字混合串的方法(String.getBytes)
2009-08-09 21:37 2137/** * 按字节截取字符串 * @para ... -
一种截取字母汉字混合串的方法(String.split)
2009-08-08 23:28 1666/** * 按字节截取字符串 * @ ...
相关推荐
主线程、生产者线程(一)、消费者管理线程(一)、消费者线程(多),以及一些全局变量。 主线程职责:UI控件的控制和显示、控制生产者:调节生产的速度和暂停与继续、控制消费 生产者线程职责:根据商品数量调控...
在操作系统领域,生产者-消费者问题是经典的问题之一,它涉及到多线程同步和资源管理。本项目通过使用多线程同步方法解决这个问题,具体表现为有界缓冲区的管理,其中包含20个存储单元,存储1~20的整型数。下面是...
**Qt入门练习项目——生产者消费者模型** 在编程领域,生产者消费者模型是一种常见的多线程同步问题的解决方案。这个模型通常用于处理数据流的异步处理,其中一个或多个线程(生产者)生成数据,而其他线程(消费者...
在生产者-消费者模型中,有两个主要的角色:生产者和消费者。生产者负责创建或生成数据,而消费者则负责消费这些数据。共享的资源通常是一个缓冲区,生产者将数据放入缓冲区,消费者从中取出数据。问题的关键在于...
### 操作系统上机实验报告:进程同步和通信——生产者和消费者问题模拟 #### 一、实验目的 本次实验的主要目的是让学生通过调试、修改、运行一个模拟程序,加深对进程概念的理解,熟悉同步和通信的过程,掌握进程...
在这个练习中,文件"P_C"可能包含了具体的源代码实现,包括生产者类和消费者类的定义,以及主程序中创建线程、启动生产者和消费者、以及必要的同步操作。通过分析和理解这段代码,可以深入学习多线程编程、同步原语...
在"并行openmp程序生产者消费者-渠涧涛-104753130775"这个文件中,可能包含了渠涧涛同学完成的源代码和相关分析。通过阅读和理解这份代码,我们可以更深入地了解如何在OpenMP环境中实现生产者消费者模式,包括线程的...
“生产者-消费者”问题通常被描述为:存在一个固定大小的缓冲区,多个生产者进程不断产生数据并将数据放入缓冲区,而多个消费者进程则不断地从缓冲区取出数据进行处理。为了保证数据的一致性和完整性,需要解决两个...
- 实现生产者消费者模型中的同步问题。 **实验内容:** - 使用信号量机制实现生产者和消费者的同步。 - 设计并实现相应的算法以解决资源竞争问题。 #### 实验五:作业调度实验 **实验目的:** - 理解作业调度的...
操作系统中的生产者与消费者问题是多线程编程中的一个经典模型,它主要研究的是如何有效地在共享资源之间协调生产者和消费者的行为,以避免数据竞争和死锁等问题。在这个C#编写的实例中,我们将深入探讨这个问题及其...
- **选项B** 这种情况构成了产品缺陷,生产者和销售者需要承担相应的法律责任。 34. **有限责任的含义:** - **选项D** 有限责任指的是股东以其出资额为限对公司承担责任,超出部分由公司独立承担。 35. **在...
5. **设计模式**:生产者消费者模型可以看作是一种“生产者-消费者”设计模式的实例,它属于行为设计模式,用于协调异步处理和共享资源。此外,还可以结合观察者模式,让消费者订阅生产者,当有新数据时,生产者通知...
标题中的“消费者生产者程序”是指在多线程编程中的一种经典模式,也称为缓冲区模型。在这种模式中,一个线程(生产者)负责创建或生成数据,另一个线程(消费者)则负责处理这些数据。这个场景通常用于并发环境,以...
在Java编程中,"生产者消费者问题"是一个经典的多线程同步问题,它涉及到了如何在多线程环境下有效地共享资源。在这个问题中,"生产者"负责创建资源,而"消费者"则负责消费这些资源。为了确保生产者不会在资源耗尽时...
# 实践并发和分布式系统============================================== 格拉纳达大学并发和分布式系统实践的一套程序。... 生产者-消费者练习实践3: 生产者-消费者运动 (mpi) 哲学家练习哲学家侍者练习
在C#编程中,"生产者消费者模型"是一种常见的多线程设计模式,它通过分离数据的生产和消费过程,使得生产者线程可以专心于创建数据,而消费者线程则专注于处理这些数据,两者互不干扰,提高了系统效率。在这个模型中...
- ①②不一定是分解者,也可能作为生产者或消费者。 12. **显微镜观察细胞:** - 显微镜放大倍率增加可能导致视野变暗。 - 低倍镜下可见的细胞,高倍镜下不一定可见。 - 高倍镜下观察到的细胞数量减少。 以上...
- 世界上最大的煤炭生产国和消费国:the world's largest producer and consumer of coal - (作为)结果,因此:as a result, therefore - 一些有用的措施:some useful measures - (我们中)没有人:none of ...