chidaodezhongsheng
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
留言簿
(2)
給我留言
查看公開留言
查看私人留言
隨筆檔案
2012年1月 (1)
2010年10月 (1)
文章檔案
2010年12月 (7)
2010年11月 (6)
2010年10月 (24)
搜索
最新評論
1.?re: Http參數傳遞時的亂碼過濾器[未登錄]
是是是是是是
--啊啊
2.?re: Servlet配置到Web.xml中
配置好了 它整體的流程是什么啊?
--Tovep
3.?re: JDBC基本操作
期待...
--Tovep
4.?re: 再寫銀行排隊
LZ 寫的不錯 啊!!!
--Tovep
5.?re: 生產消費問題
臭小子 居然FZZT
--Tovep
閱讀排行榜
1.?無題(198)
2.?很久沒更新了,真的太久了(173)
評論排行榜
1.?很久沒更新了,真的太久了(0)
2.?無題(0)
Powered by:
博客園
模板提供:
滬江博客
BlogJava
|
首頁
|
發新隨筆
|
發新文章
|
聯系
|
聚合
|
管理
生產消費問題
java中一個比較著名的問題就是生產消費問題,就是一邊生產出產品,另一邊就消費掉剛剛生產出來的產品,這里面需要用到線程同步和信號量的問題。
線程同步就是實現線程安全的一種手段,是處理資源共享問題的必須手段。假如多個線程去共享同一個資源,肯定會發生我們意想不到的問題,使得線程并不安全,例如重復取出相同資源。
而使用信號量是控制各個線程之間調用順序的方法,通過信號量讓線程不斷休息和喚醒,這樣來實現我們想要的功能。
下面看一個不加線程同步和信號量的程序:
class
Person
{
private
String name ;
private
String sex ;
public
void
set(String name,String sex)
{
this
.name
=
name;
this
.sex
=
sex;
}
public
String get()
{
return
this
.name
+
"
----
"
+
this
.sex;
}
}
class
Pro
implements
Runnable
{
Person p
=
null
;
public
Pro(Person p)
{
this
.p
=
p;
}
public
void
run()
{
int
i
=
0
;
while
(
true
)
{
if
(i
==
0
)
{
p.set(
"
林嘉綺
"
,
"
男
"
);
i
=
1
;
}
else
{
p.set(
"
香香
"
,
"
女
"
);
i
=
0
;
}
}
}
}
class
Cus
implements
Runnable
{
Person p
=
null
;
public
Cus(Person p)
{
this
.p
=
p;
}
public
void
run()
{
while
(
true
)
{
System.out.println(p.get());
try
{
Thread.sleep(
1000
);
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public
class
Test
{
public
static
void
main(String[] args)
{
Person p
=
new
Person();
Pro pro
=
new
Pro(p);
Cus cus
=
new
Cus(p);
new
Thread(pro).start();
new
Thread(cus).start();
}
}
這個程序的運行結果是:
上面那個程序會產生兩種意外:一個是當只填入一個人的姓名而未填入這個人的性別時,消費者線程就把這個人的姓名和上個人的性別聯系起來并打印輸出;另一個是生產者生產多次產品,而消費者才剛開始取出一個產品,或者是未等到生產者生產出來新產品,而消費者線程就取出多次舊產品。
這樣,我們先加上線程同步方法:在需要鎖定的資源上加上synchronized關鍵字就能保證線程同步。
附代碼:
class
Person
{
private
String name ;
private
String sex ;
public
synchronized
void
set(String name,String sex)
{
this
.name
=
name;
this
.sex
=
sex;
}
public
synchronized
String get()
{
return
this
.name
+
"
----
"
+
this
.sex;
}
}
class
Pro
implements
Runnable
{
Person p
=
null
;
public
Pro(Person p)
{
this
.p
=
p;
}
public
void
run()
{
int
i
=
0
;
while
(
true
)
{
if
(i
==
0
)
{
p.set(
"
林嘉綺
"
,
"
男
"
);
i
=
1
;
}
else
{
p.set(
"
香香
"
,
"
女
"
);
i
=
0
;
}
}
}
}
class
Cus
implements
Runnable
{
Person p
=
null
;
public
Cus(Person p)
{
this
.p
=
p;
}
public
void
run()
{
while
(
true
)
{
System.out.println(p.get());
try
{
Thread.sleep(
1000
);
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public
class
Test
{
public
static
void
main(String[] args)
{
Person p
=
new
Person();
Pro pro
=
new
Pro(p);
Cus cus
=
new
Cus(p);
new
Thread(pro).start();
new
Thread(cus).start();
}
}
這個程序的運行結果是:
上面這個程序解決了第一個問題,即當只填入一個人的姓名而未填入這個人的性別時,消費者線程就把這個人的姓名和上個人的性別聯系起來并打印輸出的問題,但是并不能解決第二個問題。若要是想解決第二個問題,我們就要添加一個信號量,控制線程之間的調用順序。
附代碼:
public
class
Food
{
private
String name;
private
String flag;
boolean
b
=
true
;
//
為true則允許生產不允許消費
//
為false則允許消費不允許生產
public
String getName()
{
return
name;
}
public
void
setName(String name)
{
this
.name
=
name;
}
public
String getFlag()
{
return
flag;
}
public
void
setFlag(String flag)
{
this
.flag
=
flag;
}
public
synchronized
void
set(String name,String flag)
{
if
(
!
b)
{
try
{
wait();
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
this
.setName(name);
this
.setFlag(flag);
b
=
false
;
notify();
}
public
synchronized
String get()
{
if
(b)
{
try
{
wait();
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
b
=
true
;
notify();
return
"
名稱:
"
+
this
.getName()
+
"
類型:
"
+
this
.getFlag();
}
}
public
class
Producer
implements
Runnable
{
private
Food food;
public
Producer(Food food)
{
this
.food
=
food;
}
public
void
run()
{
boolean
b
=
true
;
while
(
true
)
{
if
(b)
{
food.set(
"
蘋果
"
,
"
水果
"
);
b
=
false
;
}
else
{
food.set(
"
茄子
"
,
"
蔬菜
"
);
b
=
true
;
}
try
{
Thread.sleep(
1000
);
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public
class
Customer
implements
Runnable
{
private
Food food;
public
Customer(Food food)
{
this
.food
=
food;
}
public
void
run()
{
while
(
true
)
{
System.out.println(food.get());
try
{
Thread.sleep(
1000
);
}
catch
(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public
class
Test
{
public
static
void
main(String[] args)
{
Food food
=
new
Food();
Producer producer
=
new
Producer(food);
Customer customer
=
new
Customer(food);
new
Thread(producer).start();
new
Thread(customer).start();
}
}
我們看看運行結果:
綜上所述,我們要想處理線程生產和消費的問題就需要進行兩步操作:
1.線程同步:進行資源鎖定,避免各個數據之間不匹配的問題。
2.加入信號量:通過類似于開關似的信號量來控制各個線程的調度,解決了一個線程連續多次被調用的問題。
發表于 2010-11-09 01:59
遲到的鐘聲
閱讀(149)
評論(1)
編輯
收藏
評論
#
re: 生產消費問題
回復
更多評論
臭小子 居然FZZT
Tovep
評論于 2010-11-09 12:50
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
主站蜘蛛池模板:
亚洲av无码偷拍在线观看
|
亚洲综合精品香蕉久久网97
|
中文字幕亚洲精品资源网
|
日本精品久久久久久久久免费
|
在线观看www日本免费网站
|
亚洲一区二区精品视频
|
国产精品亚洲天堂
|
一本色道久久综合亚洲精品高清
|
亚洲综合久久精品无码色欲
|
免费观看美女用震蛋喷水的视频
|
国产亚洲成av片在线观看
|
免费视频成人国产精品网站
|
午夜爱爱免费视频
|
男女一边桶一边摸一边脱视频免费
|
四虎永久成人免费影院域名
|
91亚洲国产成人久久精品网址
|
一个人免费视频观看在线www
|
亚洲偷自拍拍综合网
|
男女污污污超污视频免费在线看
|
国产色爽免费视频
|
99爱在线观看免费完整版
|
亚洲va在线va天堂va四虎
|
免费91麻豆精品国产自产在线观看
|
亚洲精品福利网泷泽萝拉
|
A片在线免费观看
|
亚洲AV无码一区二区三区牲色
|
在线看片人成视频免费无遮挡
|
国产精品高清视亚洲一区二区
|
亚洲老妈激情一区二区三区
|
亚洲精品国产日韩无码AV永久免费网
|
亚洲高清视频在线播放
|
91免费人成网站在线观看18
|
亚洲成aⅴ人片在线观
|
91免费国产在线观看
|
色在线亚洲视频www
|
啦啦啦手机完整免费高清观看
|
亚洲老熟女五十路老熟女bbw
|
成全视频在线观看免费高清动漫视频下载
|
天天拍拍天天爽免费视频
|
国产精品亚洲一区二区三区在线观看
|
97se亚洲综合在线
|