JAVA線程sleep和wait方法區別


sleep 是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復,調用sleep 不會釋放對象鎖。由於沒有釋放對象鎖,所以不能調用里面的同步方法。

sleep()使當前線程進入停滯狀態(阻塞當前線程),讓出CUP的使用、目的是不讓當前線程獨自霸占該進程所獲的CPU資源,以留一定時間給其他線程執行的機會;
sleep()是Thread類的Static(靜態)的方法;因此他不能改變對象的機鎖,所以當在一個Synchronized塊中調用Sleep()方法是,線程雖然休眠了,但是對象的機鎖並木有被釋放,其他線程無法訪問這個對象(即使睡着也持有對象鎖)。
在sleep()休眠時間期滿后,該線程不一定會立即執行,這是因為其它線程可能正在運行而且沒有被調度為放棄執行,除非此線程具有更高的優先級。

wait()方法是Object類里的方法;當一個線程執行到wait()方法時,它就進入到一個和該對象相關的等待池中,同時失去(釋放)了對象的機鎖(暫時失去機鎖,wait(long timeout)超時時間到后還需要返還對象鎖);可以調用里面的同步方法,其他線程可以訪問;
wait()使用notify或者notifyAlll或者指定睡眠時間來喚醒當前等待池中的線程。
wiat()必須放在synchronized block中,否則會在program runtime時扔出”java.lang.IllegalMonitorStateException“異常。

sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常

sleep方法屬於Thread類中方法,表示讓一個線程進入睡眠狀態,等待一定的時間之后,自動醒來進入到可運行狀態,不會馬上進入運行狀態,因為線程調度機制恢復線程的運行也需要時間,一個線程對象調用了sleep方法之后,並不會釋放他所持有的所有對象鎖,所以也就不會影響其他進程對象的運行。但在sleep的過程中過程中有可能被其他對象調用它的interrupt(),產生InterruptedException異常,如果你的程序不捕獲這個異常,線程就會異常終止,進入TERMINATED狀態,如果你的程序捕獲了這個異常,那么程序就會繼續執行catch語句塊(可能還有finally語句塊)以及以后的代碼。

注意sleep()方法是一個靜態方法,也就是說他只對當前對象有效,通過t.sleep()讓t對象進入sleep,這樣的做法是錯誤的,它只會是使當前線程被sleep 而不是t線程

wait屬於Object的成員方法,一旦一個對象調用了wait方法,必須要采用notify()和notifyAll()方法喚醒該進程;如果線程擁有某個或某些對象的同步鎖,那么在調用了wait()后,這個線程就會釋放它持有的所有同步資源,而不限於這個被調用了wait()方法的對象。wait()方法也同樣會在wait的過程中有可能被其他對象調用interrupt()方法而產生

三 

這兩者的施加者是有本質區別的. 
sleep()是讓某個線程暫停運行一段時間,其控制范圍是由當前線程決定,也就是說,在線程里面決定.好比如說,我要做的事情是 "點火->燒水->煮面",而當我點完火之后我不立即燒水,我要休息一段時間再燒.對於運行的主動權是由我的流程來控制.

支持一下吆 收藏一下: 很好    

而wait(),首先,這是由某個確定的對象來調用的,將這個對象理解成一個傳話的人,當這個人在某個線程里面說"暫停!",也是 thisOBJ.wait(),這里的暫停是阻塞,還是"點火->燒水->煮飯",thisOBJ就好比一個監督我的人站在我旁邊,本來該線 程應該執行1后執行2,再執行3,而在2處被那個對象喊暫停,那么我就會一直等在這里而不執行3,但正個流程並沒有結束,我一直想去煮飯,但還沒被允許, 直到那個對象在某個地方說"通知暫停的線程啟動!",也就是thisOBJ.notify()的時候,那么我就可以煮飯了,這個被暫停的線程就會從暫停處 繼續執行.


其實兩者都可以讓線程暫停一段時間,但是本質的區別是一個線程的運行狀態控制,一個是線程之間的通訊的問題

 在java.lang.Thread類中,提供了sleep(),
而java.lang.Object類中提供了wait(), notify()和notifyAll()方法來操作線程
sleep()可以將一個線程睡眠,參數可以指定一個時間。
而wait()可以將一個線程掛起,直到超時或者該線程被喚醒。
    wait有兩種形式wait()和wait(milliseconds).
sleep和wait的區別有:
  1,這兩個方法來自不同的類分別是Thread和Object
  2,最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
  3,wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在
    任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }
   4,sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常

生產者與消費者模式:

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package  com.day19;
/**
  * 生產者與消費者線程
  * @author tenlee
  *
  */
public  class  ThreadDemo {
 
     public  static  void  main(String[] args) {
         Food food =  new  Food();
         Producter p =  new  Producter(food);
         Customer c =  new  Customer(food);
         Thread tp =  new  Thread(p);
         Thread tc =  new  Thread(c);
         tp.start();
         tc.start();
     }
}
//生產者
class  Producter  implements  Runnable {
     private  Food food;
     public  Producter(Food food) {
         this .food = food;
     }
     @Override
     public  void  run() {
         for ( int  i =  0 ; i <  50 ; i++) {
             if (i %  2  ==  0 ) { //偶數,生產xx菜
//              System.out.println("紅燒肉----生產");
//              food.setName("紅燒肉");
//              try {
//                  Thread.sleep(500);//做菜
//              } catch (InterruptedException e) {
//                  e.printStackTrace();
//              }
//              food.setEfficasy("好吃");
                 food.set( "紅燒肉" "好吃" );
                 
             else  { //奇數,生產xx菜
//              System.out.println("脆皮雞 生產");
//              food.setName("脆皮雞");
//              try {
//                  Thread.sleep(500);//做菜
//              } catch (InterruptedException e) {
//                  e.printStackTrace();
//              }
//              food.setEfficasy("香脆");
                 food.set( "脆皮雞" "香脆" );
             }
         }
     }
}
class  Customer  implements  Runnable {
     private  Food food;
     public  Customer(Food food) {
         this .food = food;
     }
     @Override
     public  void  run() {
         for ( int  i =  0 ; i <  50 ; i++){
//          try {
//              Thread.sleep(500);
//          } catch (InterruptedException e) {
//              // TODO Auto-generated catch block
//              e.printStackTrace();
//          }
//          System.out.println(food.getName() + "--->"
//                  + food.getEfficasy());
             food.get();
         }
     }
}
 
package  com.day19;
 
class  Food {
     private  String name; //菜名
     private  String efficasy; //功效
     private  boolean  flag =  true ;
     
     public  synchronized  void  set(String name, String efficasy) {
         if (!flag) { //1, 消費,不能生產
             try  {
                 this .wait(); //當前線程進入等待狀態,並讓出CPU,釋放監視器的鎖
             catch  (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         System.out.println( "shengchan "  + name +  " "  + efficasy);
         this .setName(name);
         this .setEfficasy(efficasy);
         try  {
             Thread.sleep( 500 );
         catch  (InterruptedException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         flag =  false //開始消費
         this .notify();
     }
     public  synchronized  void  get() {
         if (flag) { //true是生產
             try  {
                 this .wait();
             catch  (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
         System.out.println( this .getName() +  "xiaofei-->"  this .getEfficasy());
         try  {
             Thread.sleep( 500 );
         catch  (InterruptedException e) {
             e.printStackTrace();
         }
         flag =  true //開始生產
         this .notify();
     }
     public  Food() {
         
     }
 
     public  Food(String name, String efficasy) {
         super ();
         this .name = name;
         this .efficasy = efficasy;
     }
 
     public  String getName() {
         return  name;
     }
 
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  String getEfficasy() {
         return  efficasy;
     }
 
     public  void  setEfficasy(String efficasy) {
         this .efficasy = efficasy;
     }
}

  

www.cnblogs.com/tenlee


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM