下面通過代碼給大家介紹java多線程通訊之wait notify的區別,具體內容如下所示:
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
class res{ public string username; public string sex; } class out extends thread{ res res; public out(res res){ this .res=res; } @override public void run() { //寫操作 int count= 0 ; while ( true ){ // synchronized (res.getclass()){ if (count== 0 ){ //偶數 res.username= "小明" ; res.sex= "男" ; } else { //奇數 res.username= "小紅" ; res.sex= "女" ; } count=(count+ 1 )% 2 ; // } } } } class input extends thread{ res res; public input(res res){ this .res=res; } @override public void run() { while ( true ){ // synchronized (res.getclass()){ system.out.println(res.username+ "," +res.sex); // } } } } public class outinputthread { public static void main(string[] args) { res res = new res(); out out = new out(res); input input = new input(res); out.start(); input.start(); } } 小紅,女 小紅,女 小紅,女 小紅,女 小紅,女 小紅,女 小紅,女 小紅,女 小紅,女 |
出現以上結果??消費者一直消費或者生產者一直生產
解決方法:生產者生產完成后消費者方可消費,否者不可消費,消費者未消費或者未消費完生產者不可生產,一次生產一次消費。其實也就是保證對res共享資源的操作同一時刻僅有同一個線程進行操作,
wait、notify、notifyall方法
wait、notify、notifyall是三個定義在object類里的方法,可以用來控制線程的狀態。
這三個方法最終調用的都是jvm級的native方法。隨著jvm運行平臺的不同可能有些許差異。
如果對象調用了wait方法就會使持有該對象的線程把該對象的控制權交出去,然后處于等待狀態。當前線程從運行變為阻塞,釋放所的資源
如果對象調用了notify方法就會通知某個正在等待這個對象的控制權的線程可以繼續運行。讓持有該鎖的線程從阻塞態變為就緒。
如果對象調用了notifyall方法就會通知所有等待這個對象控制權的線程繼續運行。
注意:一定要在線程同步中使用,并且是同一個鎖的資源
通過以下方式即可完成需求。
生產者獲取res.getclass鎖后,如果flag為true生產者通過調用res.getclass.wait進行等待,此時其他線程可獲取該鎖,如果flag為false,進行生產,然后設置flag為true保證資源消費后方可再生產,接著通過notify通知其他喚醒其他線程。
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
class res{ public string username; public string sex; //true 生產者等待,消費者可消費 false生產者可以生產,消費者不可消費 public boolean flag= false ; } class out extends thread{ res res; public out(res res){ this .res=res; } @override public void run() { //寫操作 int count= 0 ; while ( true ){ synchronized (res.getclass()){ if (res.flag){ try { res.getclass().wait(); //讓當前線程從運行變為阻塞,并且釋放所的資源 } catch (interruptedexception e) { e.printstacktrace(); } } if (count== 0 ){ //偶數 res.username= "小明" ; res.sex= "男" ; } else { //奇數 res.username= "小紅" ; res.sex= "女" ; } count=(count+ 1 )% 2 ; res.flag= true ; res.getclass().notify(); } } } } class input extends thread{ res res; public input(res res){ this .res=res; } @override public void run() { while ( true ){ synchronized (res.getclass()){ if (!res.flag){ try { res.getclass().wait(); } catch (interruptedexception e) { e.printstacktrace(); } } system.out.println(res.username+ "," +res.sex); res.flag= false ; res.getclass().notify(); } } } } public class outinputthread { public static void main(string[] args) { res res = new res(); out out = new out(res); input input = new input(res); out.start(); input.start(); } } |
輸出如下:
小明,男
小紅,女
小明,男
小紅,女
小明,男
小紅,女
小明,男
小紅,女
如果去掉notify會怎樣?去掉一個?去掉兩個?
去掉一個生產者可以打印多個(但是也不多),去掉消費者僅可打印一個,去掉兩個可能不打印,也可能打印1個,所以wait、notify必須成對使用
wait(用于同步中)與sleep區別?
都是做休眠,wait需要notify
對于sleep方法,我們首先要知道該方法是屬于thread類中的。而wait方法,則是屬于object類中的。
sleep方法導致了程序暫停執行指定的時間,讓出cpu該其他線程,但是他的監控狀態依然保持者,當指定的時間到了又會自動恢復運行狀態。
在調用sleep方法的過程中,線程不會釋放對象鎖。
而當調用wait方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify方法后本線程才進入對象鎖定池準備獲取對象鎖進入運行狀態。
總結
以上所述是小編給大家介紹的java多線程通訊之wait,notify的區別詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
原文鏈接:https://www.cnblogs.com/losemyfuture/archive/2018/07/24/9357846.html