Liver's Java
我不夠貪心!其實(shí)我應(yīng)該明白,心有多貪,舞臺(tái)就會(huì)有多大!堅(jiān)持!奮斗!
BlogJava
首頁
新文章
新隨筆
聚合
管理
posts - 4, comments - 6, trackbacks - 0
再談線程:生產(chǎn)者與消費(fèi)者
昨天提到了線程,那么就不得不提到“
生產(chǎn)者與消費(fèi)者
”這樣一個(gè)經(jīng)典的
線程同步問題
。
場(chǎng)景描述:
一個(gè)倉(cāng)庫(kù),生產(chǎn)者在工廠里生產(chǎn)了產(chǎn)品后,將產(chǎn)品存放到倉(cāng)庫(kù)里,倉(cāng)庫(kù)存放數(shù)量有限,當(dāng)滿倉(cāng)后,停止生產(chǎn),直到有消費(fèi)著將產(chǎn)品消費(fèi)后才繼續(xù)生產(chǎn);消費(fèi)者從倉(cāng)庫(kù)里提取產(chǎn)品,當(dāng)倉(cāng)庫(kù)空倉(cāng)時(shí),停止消費(fèi)產(chǎn)品,直到倉(cāng)庫(kù)中有產(chǎn)品時(shí),才繼續(xù)消費(fèi)產(chǎn)品。
代碼的實(shí)現(xiàn)(調(diào)整線程sleep時(shí)間可以實(shí)現(xiàn)生產(chǎn)速度與消費(fèi)速度的不同):
TestProduceAndConsumer.java
package
com.nantian;
import
java.util.Random;
public
class
TestProduceAndConsumer
{
public
static
void
main(String[] args)
{
//
創(chuàng)建一個(gè)工廠對(duì)象
ProductFactory pf
=
new
ProductFactory();
//
創(chuàng)建一個(gè)生產(chǎn)者和一個(gè)消費(fèi)者,傳遞工廠的引用,保證兩者操作的是同一個(gè)工廠
Producer p
=
new
Producer(pf);
Consumer c
=
new
Consumer(pf);
//
啟動(dòng)兩個(gè)線程
p.start();
c.start();
}
}
//
產(chǎn)品工廠
class
ProductFactory
{
//
product表示倉(cāng)庫(kù)
private
char
[] product
=
{
'
'
,
'
'
,
'
'
,
'
'
,
'
'
}
;
//
flag標(biāo)記產(chǎn)品數(shù)量
private
int
flag
=
0
;
//
生產(chǎn)產(chǎn)品
public
synchronized
void
produceProduct(
char
p)
throws
InterruptedException
{
//
判斷產(chǎn)品是否滿倉(cāng),以便決定是否繼續(xù)生產(chǎn)
if
(flag
==
product.length)
{
this
.wait();
}
//
當(dāng)代碼執(zhí)行到這里,一定不是滿倉(cāng)狀態(tài)
product[flag
++
]
=
p;
//
查看此時(shí)倉(cāng)庫(kù)狀態(tài)(這里不屬于業(yè)務(wù)邏輯部分)
System.out.print(p
+
"
被生產(chǎn),當(dāng)前倉(cāng)庫(kù)狀態(tài):
"
);
for
(
char
tmp : product)
{
System.out.print(tmp);
}
System.out.println();
//
生產(chǎn)方法完成,如果存在等待隊(duì)列中的線程,應(yīng)該喚醒
this
.notifyAll();
}
//
消費(fèi)產(chǎn)品
public
synchronized
char
consumeProduct()
throws
InterruptedException
{
//
判斷倉(cāng)庫(kù)是否空倉(cāng),以便決定是否消費(fèi)產(chǎn)品
if
(flag
==
0
)
{
this
.wait();
}
//
當(dāng)代碼執(zhí)行到這里,一定不是空倉(cāng)狀態(tài)
char
p
=
product[
--
flag]; product[flag]
=
'
'
;
//
查看此時(shí)倉(cāng)庫(kù)狀態(tài)(這里不屬于業(yè)務(wù)邏輯部分)
System.out.print(p
+
"
被消費(fèi),當(dāng)前倉(cāng)庫(kù)狀態(tài):
"
);
for
(
char
tmp : product)
{
System.out.print(tmp);
}
System.out.println();
//
消費(fèi)方法完成,如果存在等待隊(duì)列中的線程,應(yīng)該喚醒
this
.notifyAll();
return
p;
}
}
//
生產(chǎn)者
class
Producer
extends
Thread
{
private
ProductFactory pf
=
null
;
public
Producer(ProductFactory pf)
{
this
.pf
=
pf;
}
public
void
run()
{
//
一共生產(chǎn)20個(gè)產(chǎn)品
for
(
int
i
=
0
; i
<
20
; i
++
)
{
//
隨機(jī)產(chǎn)生一個(gè)大寫字母作為產(chǎn)品
Random r
=
new
Random();
char
p
=
(
char
)(r.nextInt(
26
)
+
'
A
'
);
try
{
//
產(chǎn)品入庫(kù)
pf.produceProduct(p);
//
故意sleep,以便消費(fèi)線程有機(jī)會(huì)獲得CPU時(shí)間片,方便演示
Thread.sleep(
200
);
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
//
消費(fèi)者
class
Consumer
extends
Thread
{
private
ProductFactory pf
=
null
;
public
Consumer(ProductFactory pf)
{
this
.pf
=
pf;
}
public
void
run()
{
//
一共消費(fèi)20個(gè)產(chǎn)品
for
(
int
i
=
0
; i
<
20
; i
++
)
{
try
{
//
產(chǎn)品出庫(kù)
pf.consumeProduct();
//
故意sleep,以便生產(chǎn)線程有機(jī)會(huì)獲得CPU時(shí)間片,方便演示
//
sleep時(shí)間稍微錯(cuò)開,阻止同時(shí)競(jìng)爭(zhēng)CPU時(shí)間片
Thread.sleep(
300
);
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
posted on 2009-06-04 10:57
Liver
閱讀(1426)
評(píng)論(4)
編輯
收藏
所屬分類:
CoreJava
FeedBack:
#
re: 再談線程:生產(chǎn)者與消費(fèi)者
2009-06-04 16:22 |
wuzhongxing
利用jdk1.5的concurrent包里面的blockqueue,實(shí)現(xiàn)這種模式還是比較簡(jiǎn)單的
回復(fù)
更多評(píng)論
#
re: 再談線程:生產(chǎn)者與消費(fèi)者
2009-06-04 18:10 |
樂蜂
實(shí)現(xiàn)這種模式還是比較簡(jiǎn)單的
回復(fù)
更多評(píng)論
#
re: 再談線程:生產(chǎn)者與消費(fèi)者[未登錄]
2009-06-06 16:57 |
charlee
// 判斷產(chǎn)品是否滿倉(cāng),以便決定是否繼續(xù)生產(chǎn)
if (flag == product.length) {
this.wait();
}
// 判斷倉(cāng)庫(kù)是否空倉(cāng),以便決定是否消費(fèi)產(chǎn)品
if(flag == 0) {
this.wait();
}
為什么要用if呢?你不覺得while更好么?
回復(fù)
更多評(píng)論
#
re: 再談線程:生產(chǎn)者與消費(fèi)者
2009-06-15 15:53 |
分享愛的空間
言簡(jiǎn)意賅,不錯(cuò)。。。。
希望看到更加深入的。
回復(fù)
更多評(píng)論
新用戶注冊(cè)
刷新評(píng)論列表
只有注冊(cè)用戶
登錄
后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
相關(guān)文章:
再談線程:生產(chǎn)者與消費(fèi)者
線程7種狀態(tài)的相互轉(zhuǎn)換
<
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
常用鏈接
我的隨筆
我的評(píng)論
我的參與
最新評(píng)論
留言簿
給我留言
查看公開留言
查看私人留言
隨筆分類
(5)
CoreJava(2)
Oracle
Server(1)
WebService(2)
隨筆檔案
(5)
2010年5月 (1)
2010年4月 (1)
2009年6月 (2)
2009年5月 (1)
搜索
最新評(píng)論
1.?re: 線程7種狀態(tài)的相互轉(zhuǎn)換
不錯(cuò)不錯(cuò),分析的好。
--11
2.?re: 線程7種狀態(tài)的相互轉(zhuǎn)換
好!
--yjw
3.?re: 再談線程:生產(chǎn)者與消費(fèi)者
言簡(jiǎn)意賅,不錯(cuò)。。。。
希望看到更加深入的。
--分享愛的空間
4.?re: 再談線程:生產(chǎn)者與消費(fèi)者[未登錄]
評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
--charlee
5.?re: 再談線程:生產(chǎn)者與消費(fèi)者
實(shí)現(xiàn)這種模式還是比較簡(jiǎn)單的
--樂蜂
閱讀排行榜
1.?Tomcat下配置JNDI數(shù)據(jù)庫(kù)連接池并使用(3279)
2.?線程7種狀態(tài)的相互轉(zhuǎn)換(2190)
3.?再談線程:生產(chǎn)者與消費(fèi)者(1426)
4.?[轉(zhuǎn)載]Java遠(yuǎn)程通訊技術(shù)總結(jié)(372)
5.?[轉(zhuǎn)載]Web Services&XML:什么是Web Service(233)
評(píng)論排行榜
1.?再談線程:生產(chǎn)者與消費(fèi)者(4)
2.?線程7種狀態(tài)的相互轉(zhuǎn)換(2)
3.?Tomcat下配置JNDI數(shù)據(jù)庫(kù)連接池并使用(0)
4.?[轉(zhuǎn)載]Java遠(yuǎn)程通訊技術(shù)總結(jié)(0)
5.?[轉(zhuǎn)載]Web Services&XML:什么是Web Service(0)
Copyright ©2025 Liver Powered By
博客園
模板提供:
滬江博客
主站蜘蛛池模板:
免费无码又爽又刺激一高潮
|
本免费AV无码专区一区
|
国产成人亚洲午夜电影
|
又硬又粗又长又爽免费看
|
99免费精品视频
|
亚洲最大免费视频网
|
日韩精品无码区免费专区
|
免费v片在线观看
|
亚洲色婷婷六月亚洲婷婷6月
|
亚洲黄色片免费看
|
亚洲欧美日韩中文二区
|
高清免费久久午夜精品
|
蜜桃成人无码区免费视频网站
|
亚洲Av永久无码精品黑人
|
黄床大片30分钟免费看
|
鲁丝片一区二区三区免费
|
免费看成人AA片无码视频羞羞网
|
国产美女精品久久久久久久免费
|
久久综合亚洲鲁鲁五月天
|
亚洲欧洲日产国产最新
|
特黄特色大片免费
|
无码精品一区二区三区免费视频
|
区三区激情福利综合中文字幕在线一区亚洲视频1
|
最近2022中文字幕免费视频
|
毛片a级毛片免费播放下载
|
www亚洲精品少妇裸乳一区二区
|
亚洲日韩中文无码久久
|
亚洲国产精品成人综合色在线婷婷
|
亚洲欧美熟妇综合久久久久
|
国产免费网站看v片在线
|
中文字幕无码视频手机免费看
|
亚洲国产成人精品91久久久
|
亚洲AV无码不卡无码
|
亚洲女子高潮不断爆白浆
|
一个人看的www免费视频在线观看
|
日本XXX黄区免费看
|
亚洲一区二区视频在线观看
|
亚洲国产成人va在线观看网址
|
一级成人a免费视频
|
免费无码黄十八禁网站在线观看
|
国产偷国产偷亚洲清高动态图
|