Liver's Java
我不够贪心!其实我应该明白,心有多贪,舞台就会有多大!坚持!奋斗!
BlogJava
首页
新文章
新随笔
聚合
管理
posts - 4, comments - 6, trackbacks - 0
再谈线程:生产者与消费者
昨天提到了线程,那么就不得不提到“
生产者与消费者
”这样一个经典的
线程同步问题
。
场景描述:
一个仓库,生产者在工厂里生产了产品后,将产品存放到仓库里,仓库存放数量有限,当满仓后,停止生产,直到有消费着将产品消费后才继续生产;消费者从仓库里提取产品,当仓库空仓时,停止消费产品,直到仓库中有产品时,才继续消费产品。
代码的实现(调整线程sleep时间可以实现生产速度与消费速度的不同):
TestProduceAndConsumer.java
package
com.nantian;
import
java.util.Random;
public
class
TestProduceAndConsumer
{
public
static
void
main(String[] args)
{
//
创建一个工厂对象
ProductFactory pf
=
new
ProductFactory();
//
创建一个生产者和一个消费者,传递工厂的引用,保证两者操作的是同一个工厂
Producer p
=
new
Producer(pf);
Consumer c
=
new
Consumer(pf);
//
启动两个线程
p.start();
c.start();
}
}
//
产品工厂
class
ProductFactory
{
//
product表示仓库
private
char
[] product
=
{
'
'
,
'
'
,
'
'
,
'
'
,
'
'
}
;
//
flag标记产品数量
private
int
flag
=
0
;
//
生产产品
public
synchronized
void
produceProduct(
char
p)
throws
InterruptedException
{
//
判断产品是否满仓,以便决定是否继续生产
if
(flag
==
product.length)
{
this
.wait();
}
//
当代码执行到这里,一定不是满仓状态
product[flag
++
]
=
p;
//
查看此时仓库状态(这里不属于业务逻辑部分)
System.out.print(p
+
"
被生产,当前仓库状态:
"
);
for
(
char
tmp : product)
{
System.out.print(tmp);
}
System.out.println();
//
生产方法完成,如果存在等待队列中的线程,应该唤醒
this
.notifyAll();
}
//
消费产品
public
synchronized
char
consumeProduct()
throws
InterruptedException
{
//
判断仓库是否空仓,以便决定是否消费产品
if
(flag
==
0
)
{
this
.wait();
}
//
当代码执行到这里,一定不是空仓状态
char
p
=
product[
--
flag]; product[flag]
=
'
'
;
//
查看此时仓库状态(这里不属于业务逻辑部分)
System.out.print(p
+
"
被消费,当前仓库状态:
"
);
for
(
char
tmp : product)
{
System.out.print(tmp);
}
System.out.println();
//
消费方法完成,如果存在等待队列中的线程,应该唤醒
this
.notifyAll();
return
p;
}
}
//
生产者
class
Producer
extends
Thread
{
private
ProductFactory pf
=
null
;
public
Producer(ProductFactory pf)
{
this
.pf
=
pf;
}
public
void
run()
{
//
一共生产20个产品
for
(
int
i
=
0
; i
<
20
; i
++
)
{
//
随机产生一个大写字母作为产品
Random r
=
new
Random();
char
p
=
(
char
)(r.nextInt(
26
)
+
'
A
'
);
try
{
//
产品入库
pf.produceProduct(p);
//
故意sleep,以便消费线程有机会获得CPU时间片,方便演示
Thread.sleep(
200
);
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
//
消费者
class
Consumer
extends
Thread
{
private
ProductFactory pf
=
null
;
public
Consumer(ProductFactory pf)
{
this
.pf
=
pf;
}
public
void
run()
{
//
一共消费20个产品
for
(
int
i
=
0
; i
<
20
; i
++
)
{
try
{
//
产品出库
pf.consumeProduct();
//
故意sleep,以便生产线程有机会获得CPU时间片,方便演示
//
sleep时间稍微错开,阻止同时竞争CPU时间片
Thread.sleep(
300
);
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
posted on 2009-06-04 10:57
Liver
阅读(1417)
评论(4)
编辑
收藏
所属分类:
CoreJava
FeedBack:
#
re: 再谈线程:生产者与消费者
2009-06-04 16:22 |
wuzhongxing
利用jdk1.5的concurrent包里面的blockqueue,实现这种模式还是比较简单的
回复
更多评论
#
re: 再谈线程:生产者与消费者
2009-06-04 18:10 |
乐蜂
实现这种模式还是比较简单的
回复
更多评论
#
re: 再谈线程:生产者与消费者[未登录]
2009-06-06 16:57 |
charlee
// 判断产品是否满仓,以便决定是否继续生产
if (flag == product.length) {
this.wait();
}
// 判断仓库是否空仓,以便决定是否消费产品
if(flag == 0) {
this.wait();
}
为什么要用if呢?你不觉得while更好么?
回复
更多评论
#
re: 再谈线程:生产者与消费者
2009-06-15 15:53 |
分享爱的空间
言简意赅,不错。。。。
希望看到更加深入的。
回复
更多评论
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
相关文章:
再谈线程:生产者与消费者
线程7种状态的相互转换
<
2009年6月
>
日
一
二
三
四
五
六
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
给我留言
查看公开留言
查看私人留言
随笔分类
(5)
CoreJava(2)
Oracle
Server(1)
WebService(2)
随笔档案
(5)
2010年5月 (1)
2010年4月 (1)
2009年6月 (2)
2009年5月 (1)
搜索
最新评论
1. re: 线程7种状态的相互转换
不错不错,分析的好。
--11
2. re: 线程7种状态的相互转换
好!
--yjw
3. re: 再谈线程:生产者与消费者
言简意赅,不错。。。。
希望看到更加深入的。
--分享爱的空间
4. re: 再谈线程:生产者与消费者[未登录]
评论内容较长,点击标题查看
--charlee
5. re: 再谈线程:生产者与消费者
实现这种模式还是比较简单的
--乐蜂
阅读排行榜
1. Tomcat下配置JNDI数据库连接池并使用(3259)
2. 线程7种状态的相互转换(2173)
3. 再谈线程:生产者与消费者(1417)
4. [转载]Java远程通讯技术总结(362)
5. [转载]Web Services&XML:什么是Web Service(221)
评论排行榜
1. 再谈线程:生产者与消费者(4)
2. 线程7种状态的相互转换(2)
3. Tomcat下配置JNDI数据库连接池并使用(0)
4. [转载]Java远程通讯技术总结(0)
5. [转载]Web Services&XML:什么是Web Service(0)