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
遲到的鐘聲
閱讀(150)
評論(1)
編輯
收藏
評論
#
re: 生產消費問題
回復
更多評論
臭小子 居然FZZT
Tovep
評論于 2010-11-09 12:50
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
網站導航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
主站蜘蛛池模板:
四虎精品成人免费视频
|
日本在线看片免费
|
国产精品亚洲产品一区二区三区
|
99热在线免费播放
|
亚洲最大中文字幕无码网站
|
亚洲AV日韩精品一区二区三区
|
免费h视频在线观看
|
亚洲无人区码一二三码区别图片
|
久久久久亚洲精品天堂久久久久久
|
中文字幕亚洲免费无线观看日本
|
国产精品日本亚洲777
|
亚洲成人精品久久
|
日本免费一二区在线电影
|
黄色视屏在线免费播放
|
67194在线午夜亚洲
|
亚洲人成色777777在线观看
|
女人张开腿给人桶免费视频
|
日本免费大黄在线观看
|
久久综合亚洲色hezyo
|
少妇中文字幕乱码亚洲影视
|
亚洲人成人网毛片在线播放
|
久久精品夜色噜噜亚洲A∨
|
无码日韩人妻av一区免费
|
a级日本高清免费看
|
黑人粗长大战亚洲女2021国产精品成人免费视频
|
五月婷婷在线免费观看
|
日韩毛片一区视频免费
|
亚洲免费网站在线观看
|
亚洲综合区小说区激情区
|
亚洲国产精品第一区二区三区
|
在线观看无码AV网站永久免费
|
免费无码av片在线观看
|
日本一区二区三区免费高清在线
|
亚洲免费福利视频
|
亚洲成AV人片在线播放无码
|
亚洲国产精品碰碰
|
国产一级淫片a免费播放口之
|
97性无码区免费
|
99免费在线观看视频
|
两性色午夜视频免费播放
|
免费福利在线观看
|