java線程 - 線程喚醒后並被執行時,是在上次阻塞的代碼行重新往下執行,而不是從頭開始執行


今天重新把昨晚的線程同步面試題做一遍時,發現實際情況運行下來時,線程一直不同步。后來經過不斷測試,發現自己的一個誤區。

之前一直以為,線程如果被喚醒后再次執行時,會從頭開始運行這個線程,也就是重新運行Runnable中的run()方法;

而實際情況是,被喚醒並且被執行的線程是從上次阻塞的位置從下開始運行,也就是從wait()方法后開始執行。

所以判斷是否進入某一線程的條件 是用while判斷,而不是用If判斷判斷。

 

下面舉例說明:

如果三個線程同步工作,第一個線程打印1,2,3,4,5   ,然后第二個線程打印1,2,3,4,5  ,接着第三個線程也打印 1,2,3,4,5,重復100次。

 1 public class Thread_test {
 2     
 3     static final manage m = new manage();
 4     
 5     public static void main(String[] args) {
 6         //線程一
 7         new Thread(new Runnable() {            
 8             @Override
 9             public void run() {
10                 // TODO Auto-generated method stub
11                 for(int i=0;i<50;i++){
12                     m.threadPrint(i,0);
13                 }
14             }
15         }).start();
16         
17         //線程二
18         new Thread(new Runnable(){
19             
20             public void run(){
21                 for(int i=0;i<50;i++){
22                     m.threadPrint(i,1);
23                 }
24             }
25         }).start();
26         
27                 //線程三
28         new Thread(new Runnable(){
29             
30             public void run(){
31                 for(int i=0;i<50;i++){
32                     m.threadPrint(i,2);
33                 }
34             }
35         }).start();
36 
37     }
38 
39 }
40 
41 
42 //控制線程執行的順序
43 class manage{
44        //權限,0代表1號線程執行,1代表二號線程執行,2代表三號線程執行
45     private int isA = 0;
46     
47     public synchronized void threadPrint(int i,int n){
48           /*該處應用while來判斷是否輪到該線程執行,假如用If判斷的話,如果該線程阻塞后再次被喚醒執行時(其他線程調用this.notifyAll()),
他會從this.wait()后面的代碼開始執行,即時沒輪到該線程執行*/
49 while(this.isA != n){ 50 try {
this.wait(); 53 } catch (Exception e) { 54 // TODO: handle exception 55 } 56 } 57 for(int j=0;j<5;j++){ 58 System.out.println(Thread.currentThread().getName()+":"+(j+1)+" loop in "+(i+1)); 59 } 60 this.isA = (this.isA+1)%3;//將權限傳遞給后一個進程62 this.notifyAll(); 63 } 64 65 66 67 }

 


免責聲明!

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



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