- 浏览: 696551 次
- 性别:
- 来自: 杭州
文章分类
最新评论
这学期,应聘的时候有一些是线程相关的,虽然自己对线程编程有点概念,但没有写过经典的例子。放假了有点时候,就想写多线程的例子。
笔试的题目类似地:一个生产者一次生产10个,满了后通知消费者,然后等待。一个消费者产品有满了就消费。到空时通知生产者,然后等待。
那时对等待/通知机制没怎么写过,那次笔试应该写的大概对(想法对),但写的wait()和notifyAll()的位置不对。现在有时间就写了这个例子。
描述:生产者一次生产N个产品,池中达到M就等待,通知等待的消费者。消费者有产品就消费,到没有时就通知生产者,然后等待。
1.生产者:
2.消费者:
3.Demo
注意:等待时候要用pool.wait()因为同步的是pool。否则会抛出java.lang.IllegalMonitorStateException
^_^
代码下载
笔试的题目类似地:一个生产者一次生产10个,满了后通知消费者,然后等待。一个消费者产品有满了就消费。到空时通知生产者,然后等待。
那时对等待/通知机制没怎么写过,那次笔试应该写的大概对(想法对),但写的wait()和notifyAll()的位置不对。现在有时间就写了这个例子。
描述:生产者一次生产N个产品,池中达到M就等待,通知等待的消费者。消费者有产品就消费,到没有时就通知生产者,然后等待。
1.生产者:
package net.blogjava.chenlb.multithreaded;
import java.util.List;
/**
* @author chenlb
*
* 生产者.<br/>
* 默认产品池大小M=20,产品梯阶大小N=5.在生产过程中,池的大小会超过20,但池中最大应该是M+N-1.
*/
public class Producer implements Runnable {
/**
* 池默认大小
*/
public static final int DEFALUT_SIZE = 20;
/**
* 默认一次生产的数量
*/
public static final int DEFALUT_STEP_SIZE = 5;
private static int PRODUCER_ID = 0; //生产者号
private List<Product> pool = null;
private int size = DEFALUT_SIZE;
private int stepSize = DEFALUT_STEP_SIZE;
private String name = "Producer_"+(++PRODUCER_ID); //生产者名
private boolean isRun = true;
/**
* 默认产品池大小20, 默认产品增长梯阶大小5
*/
public Producer(List<Product> pool) {
this.pool = pool;
}
/**
* @param pool
* @param size 池大小
*/
public Producer(List<Product> pool, int size) {
this.pool = pool;
this.size = size;
}
/**
* @param pool
* @param size 池大小
* @param stepSize 一次生产多少
*/
public Producer(List<Product> pool, int size, int stepSize) {
this.pool = pool;
this.size = size;
this.stepSize = stepSize;
}
public void run() {
// TODO 生产者线程
//int pi = 0;
while(isRun) {//&& pi<10
//pi++;
synchronized (pool) { //同步产品池
if(pool.size() >= size) {
try {
System.out.println(name+" 等待!");
pool.wait(); //同步什么就等待什么,否则抛出java.lang.IllegalMonitorStateException
} catch (InterruptedException e) {
isRun = false;
System.out.println(name+" thread interrupt!");
}
} else {
for(int i=0; i<stepSize; i++) { //一次生产stepSize个产品
pool.add(product()); //生产产品
}
System.out.println("产品池中有: "+pool.size());
pool.notifyAll(); //通知等待的线程(主要用来通知消费者, 但生产者线程也会通知到)
}
}
try {
System.out.println(name+" 休息1秒!");
Thread.sleep(1000); //调试用
} catch (InterruptedException e) {
System.out.println(name+" sleep 1s thread interrupt");
}
}
System.out.println(name+" end! pool size: "+pool.size());
}
private static int P_ID = 0;
/**
* 生产产品
* @return 产品
*/
private Product product() {
String name = "product_"+(++P_ID);
System.out.println(this.name+" 生产了: "+name);
return new Production(name);
}
}
import java.util.List;
/**
* @author chenlb
*
* 生产者.<br/>
* 默认产品池大小M=20,产品梯阶大小N=5.在生产过程中,池的大小会超过20,但池中最大应该是M+N-1.
*/
public class Producer implements Runnable {
/**
* 池默认大小
*/
public static final int DEFALUT_SIZE = 20;
/**
* 默认一次生产的数量
*/
public static final int DEFALUT_STEP_SIZE = 5;
private static int PRODUCER_ID = 0; //生产者号
private List<Product> pool = null;
private int size = DEFALUT_SIZE;
private int stepSize = DEFALUT_STEP_SIZE;
private String name = "Producer_"+(++PRODUCER_ID); //生产者名
private boolean isRun = true;
/**
* 默认产品池大小20, 默认产品增长梯阶大小5
*/
public Producer(List<Product> pool) {
this.pool = pool;
}
/**
* @param pool
* @param size 池大小
*/
public Producer(List<Product> pool, int size) {
this.pool = pool;
this.size = size;
}
/**
* @param pool
* @param size 池大小
* @param stepSize 一次生产多少
*/
public Producer(List<Product> pool, int size, int stepSize) {
this.pool = pool;
this.size = size;
this.stepSize = stepSize;
}
public void run() {
// TODO 生产者线程
//int pi = 0;
while(isRun) {//&& pi<10
//pi++;
synchronized (pool) { //同步产品池
if(pool.size() >= size) {
try {
System.out.println(name+" 等待!");
pool.wait(); //同步什么就等待什么,否则抛出java.lang.IllegalMonitorStateException
} catch (InterruptedException e) {
isRun = false;
System.out.println(name+" thread interrupt!");
}
} else {
for(int i=0; i<stepSize; i++) { //一次生产stepSize个产品
pool.add(product()); //生产产品
}
System.out.println("产品池中有: "+pool.size());
pool.notifyAll(); //通知等待的线程(主要用来通知消费者, 但生产者线程也会通知到)
}
}
try {
System.out.println(name+" 休息1秒!");
Thread.sleep(1000); //调试用
} catch (InterruptedException e) {
System.out.println(name+" sleep 1s thread interrupt");
}
}
System.out.println(name+" end! pool size: "+pool.size());
}
private static int P_ID = 0;
/**
* 生产产品
* @return 产品
*/
private Product product() {
String name = "product_"+(++P_ID);
System.out.println(this.name+" 生产了: "+name);
return new Production(name);
}
}
2.消费者:
package net.blogjava.chenlb.multithreaded;
import java.util.List;
/**
* @author chenlb
*
* 消费者
*/
public class Consumer implements Runnable {
private static int C_ID = 0; //消费者ID
private List<Product> pool = null;
private String name = "Consumer_"+(++C_ID);
private boolean isRun = true;
public Consumer(List<Product> pool) {
this.pool = pool;
}
public void run() {
// TODO 消费者线程
//int pi = 0;
while(isRun) {//&& pi<10
//pi++;
synchronized (pool) {
if(pool.size() < 1) {
try {
System.out.println(name+" 等待!");
pool.notifyAll(); //通知线程(主要是生产者,但也会通知到生产者线程)
pool.wait();
} catch (InterruptedException e) {
isRun = false;
System.out.println(name+" thread interrupt!");
}
} else {
Product p = pool.remove(0); //消费
printProduct(p);
}
}
try {
Thread.sleep(1000); //调试用
} catch (InterruptedException e) {
System.out.println(name+" sleep 1s thread interrupt");
}
}
System.out.println(name+" end! pool size: "+pool.size());
}
private void printProduct(Product p) {
System.out.println(name+" 消费了: "+p.getName());
}
}
import java.util.List;
/**
* @author chenlb
*
* 消费者
*/
public class Consumer implements Runnable {
private static int C_ID = 0; //消费者ID
private List<Product> pool = null;
private String name = "Consumer_"+(++C_ID);
private boolean isRun = true;
public Consumer(List<Product> pool) {
this.pool = pool;
}
public void run() {
// TODO 消费者线程
//int pi = 0;
while(isRun) {//&& pi<10
//pi++;
synchronized (pool) {
if(pool.size() < 1) {
try {
System.out.println(name+" 等待!");
pool.notifyAll(); //通知线程(主要是生产者,但也会通知到生产者线程)
pool.wait();
} catch (InterruptedException e) {
isRun = false;
System.out.println(name+" thread interrupt!");
}
} else {
Product p = pool.remove(0); //消费
printProduct(p);
}
}
try {
Thread.sleep(1000); //调试用
} catch (InterruptedException e) {
System.out.println(name+" sleep 1s thread interrupt");
}
}
System.out.println(name+" end! pool size: "+pool.size());
}
private void printProduct(Product p) {
System.out.println(name+" 消费了: "+p.getName());
}
}
3.Demo
package net.blogjava.chenlb.multithreaded;
import java.util.LinkedList;
import java.util.List;
/**
* @author chenlb
*
*/
public class Sale {
public static void main(String[] args) {
//链表产品池
List<Product> pool = new LinkedList<Product>();
//两个生产者
Producer p1 = new Producer(pool);
Producer p2 = new Producer(pool);
Thread tp1 = new Thread(p1);
Thread tp2 = new Thread(p2);
tp1.start();
tp2.start();
//两个消费者
Consumer c1 = new Consumer(pool);
Consumer c2 = new Consumer(pool);
Thread tc1 = new Thread(c1);
Thread tc2 = new Thread(c2);
tc1.start();
tc2.start();
}
}
import java.util.LinkedList;
import java.util.List;
/**
* @author chenlb
*
*/
public class Sale {
public static void main(String[] args) {
//链表产品池
List<Product> pool = new LinkedList<Product>();
//两个生产者
Producer p1 = new Producer(pool);
Producer p2 = new Producer(pool);
Thread tp1 = new Thread(p1);
Thread tp2 = new Thread(p2);
tp1.start();
tp2.start();
//两个消费者
Consumer c1 = new Consumer(pool);
Consumer c2 = new Consumer(pool);
Thread tc1 = new Thread(c1);
Thread tc2 = new Thread(c2);
tc1.start();
tc2.start();
}
}
注意:等待时候要用pool.wait()因为同步的是pool。否则会抛出java.lang.IllegalMonitorStateException
^_^
代码下载
发表评论
-
不抛出越界异常的求子串方法
2008-06-18 14:36 1216用String.substring方法,不小心会有越界异 ... -
java -D参数简化加入多个jar
2008-05-30 11:22 1987java命令引入jar时可以-cp参数,但时-cp不 ... -
[原]自己实现的优先队列 PriorityQueue
2008-05-08 23:08 2099java库里的PriorityQueue无法满足我,它 ... -
poi会中文乱码,Jexcelapi不会
2007-03-21 19:06 2268目前比较流行的生成Excel文件的有poi和Jexcelapi ... -
itest生成pdf中文为空白
2007-03-21 19:52 2561要下载iTextAsian.jar地址: http://prd ... -
[转载]jsp 实现 word, excel
2007-08-22 13:15 1492这里使用一个小技巧,就是先将其转换为可编辑的JSP文件,然后再 ... -
jsp 提交表单中文问题解决
2007-09-09 09:47 1459用过虑器,但只对post有效,get方式请看。http ... -
Weblogic 中部署 Web 应用程序
2007-09-22 18:48 34191、安装好weblogic8.1 2、 ... -
weblogic 8.1.4服务器挂起,出现StuckThreadMaxTime错误
2007-10-06 21:10 9042前几天用spring+hibernate+struts写了个增 ... -
weblogic8.1作为windows服务运行
2007-10-06 23:02 1650实验室机房里安装的Weblogic 每次想打开网页 ... -
jsp 下载文件
2007-10-16 23:57 2010jsp 直接输出二进制文件怎么办呢? downl ... -
java 压缩目录为 zip
2007-10-18 13:53 2110用java好久了,还没有写个压缩文件的示例,昨晚弄 ... -
jstl 1.0 formatDate yyyy-mm 不能正常工作
2007-10-25 22:38 1103jstl 1.0 formatDate yyyy-m ... -
jxl 写 excel
2007-10-29 10:52 1321项目中要写excel,把这个例子写出来,以后可以看 ... -
jxl 读 excel
2007-10-29 11:04 1461与写对应的是读. package net.bl ... -
ant build 出现 warning modified in the future
2007-12-13 23:13 1744今天同学想rebuild项目源码,但出现上面情况。 ... -
ant 编译特定包下面的源文件
2007-12-15 12:13 1712项目中有applet,现在想只编译applet包下 ... -
Java读RTF乱码问题
2008-02-01 17:05 6897这几天想用Java读富文档。用javax.swing. ... -
System.in重复接收用户输入一行命令
2008-03-11 21:49 1647以前想用循环来System.in (或是其它输入方式老 ... -
下载文件保存提示文件名显示中文
2008-03-16 14:29 1191用URLEncoder转换。 String file ...
相关推荐
记录型信号量通常用于解决生产者-消费者问题,因为它可以记录缓冲池中的空缓冲区和满缓冲区的数量,从而实现生产者和消费者的同步。 解决生产者-消费者问题的方法 为了解决生产者-消费者问题,我们可以使用记录型...
生产者-消费者问题是操作系统中经典的问题之一,它是指在多线程环境下,多个生产者线程和消费者线程访问同一个共享缓冲区,导致缓冲区的数据混乱和不一致的问题。 在解决生产者-消费者问题时,需要使用同步机制来...
在生产者-消费者问题中,可以使用互斥量(mutex)保证缓冲区的独占访问,以及使用条件变量(condition variable)实现生产者等待消费者消费或消费者等待生产者生产。 4. **互斥量**:互斥量用于实现对共享资源的...
1、设计目的:通过研究Linux的进程机制和信号量,实现生产者消费者问题的并发控制。 2、说明:有界缓冲区内设有20个存储单元,放入取出的产品设定为1-20个整数。 3、设计要求: 生产者和消费者进程的数目不固定,可...
生产者-消费者问题是操作系统中经典的进程同步问题,它模拟了实际生产环境中的资源分配与消耗。在这个问题中,生产者进程负责生成数据并放入有限大小的缓冲区,而消费者进程则从缓冲区取出数据进行消费。为了确保...
生产者-消费者模型通常包括两个角色:生产者进程负责生成数据,而消费者进程则负责消费这些数据。在一个共同的数据缓冲区中,生产者将产品放入,消费者从中取出。关键在于,当缓冲区满时,生产者应停止生产直到消费...
"生产者-消费者"问题是一种经典的多线程同步问题,源于计算机科学中的操作系统领域,用于描述在并发环境中如何协调生产者和消费者之间的操作,确保数据的一致性和避免资源浪费。这个问题的基本设定是有一个共享缓冲...
生产者-消费者问题是这种并发模型的一个经典案例,它涉及到如何在多个线程间共享资源,确保数据的一致性和正确性。在这个场景中,生产者线程负责生成数据并放入一个有限的缓冲区,而消费者线程则负责从缓冲区取出...
1.利用记录型信号量解决生产者-消费者问题.odt1.利用记录型信号量解决生产者-消费者问题.odt1.利用记录型信号量解决生产者-消费者问题.odt
结合System V信号量机制,利用Linux下的多线程库实现了Linux下的操作系统生产者-消费者模型,具体原理可参考博文:: http://blog.csdn.net/Mikeoperfect/article/details/79431642
"生产者-消费者"问题描述的是两个或多个进程之间的协作:生产者进程负责生成数据(产品),而消费者进程则负责消耗这些数据。为了确保系统的稳定性和正确性,必须防止生产者过快地生产数据导致缓冲区溢出,或者消费...
以记录型信号量实现生产者-消费者问题 实验目的: 1.加深对进程同步概念的理解。 2.理解多道程序环境中,不同进程对资源访问及相互合作进程的关系的处理方法。 实验要求: 利用C语言程序模拟生产者-消费者问题和哲学...
《生产者-消费者问题在C++中的实现》 生产者-消费者问题是多线程编程中的经典案例,它展示了如何在并发环境中实现线程间的同步与互斥。在本项目中,我们将探讨这个问题,并以C++语言为基础,创建一个在Windows 2000...
### 生产者-消费者问题详解 #### 一、问题背景与意义 生产者-消费者问题,作为操作系统领域经典的同步问题之一,广泛应用于多线程环境下资源共享的场景。它描述了一个或多个人(生产者)向一个有限容量的缓冲区中...
在生产者-消费者问题中,需要确保消费者不会从空缓冲区中读取数据,同时生产者也不会向满缓冲区写入数据。 - **互斥**:指同一时间内只有一个进程可以访问某个资源或执行某段代码。在本例中,有界缓冲区作为一个...
生产者-消费者问题是在有界缓冲上操作的,它利用 N 个字节的共享内存作为有界循环缓冲区,生产者线程不断顺序地将 0 到 100 的数字写入共享的循环缓冲区,同时消费者线程不断地从共享的循环缓冲区读取数据。...
- 在生产者-消费者问题中,对缓冲区的读写操作需要互斥锁来保护,确保在任一时刻,只允许一个线程(生产者或消费者)操作缓冲区。 5. **信号量**: - 信号量是另一种同步机制,它可以表示和控制资源的数量。 - ...
生产者-消费者模型涉及到两个主要角色:生产者(Producer)和消费者(Consumer)。生产者负责生成数据或产品,并将其放入一个共享的缓冲区;而消费者则从这个缓冲区中取出并消费这些数据或产品。在我们的例子中,有...
生产者-消费者问题的基本情景是这样的:一个系统中有两个角色,即生产者和消费者。生产者负责生成数据,而消费者则负责处理这些数据。在实际应用中,这可能意味着生产者在内存中创建数据结构(如队列),然后消费者...