多線程-使線程具有有序性


使線程具有有序性:

線程在運行時多個線程之間執行的時機是無序的,下面通過改造代碼實現運行具有有序性:

 1 /**
 2  *    線程類
 3  */
 4 public class MyThread extends Thread {
 5     private Object lock;
 6     private String showChar;
 7     private int showNumPosition;
 8     private int printCount = 0;//統計打印了幾個字母
 9     volatile private static int addNumber = 1;
10     
11     //構造
12     public MyThread(Object lock, String showChar, int showNumPosition) {
13         this.lock = lock;
14         this.showChar = showChar;
15         this.showNumPosition = showNumPosition;
16     }
17     
18     @Override
19     public void run() {
20         try {
21             synchronized(lock) {
22                 while(true) {
23                     if(addNumber % 3 == showNumPosition) {
24                         System.out.println("ThreadName = " + Thread.currentThread().getName() 
25                                 + " runCount" + addNumber + " " + showChar);
26                         lock.notifyAll();
27                         addNumber++;
28                         printCount++;
29                         if(printCount == 3) {
30                             break;
31                         }
32                     }else {
33                         lock.wait();
34                     }
35                 }
36             }
37         } catch (InterruptedException e) {
38             e.printStackTrace();
39         }
40     }
41 }
 1 /**
 2  *    測試,線程有序執行打印
 3  */
 4 public class Run {
 5     /**
 6      *    線程執行分析:
 7      *        當三個線程啟動后,如果是b和c線程拿到鎖,則會進入到else中線程等待
 8      *        printCount為每個線程私有的變量,也就是每個線程都會執行三次后不再循環
 9      *        addNumber為線程共享變量,三個線程分別運行結束之后addNumber累加
10      *    運行結果如下:
11      *        ThreadName = Thread-0 runCount1 A
12      *        ThreadName = Thread-1 runCount2 B
13      *        ThreadName = Thread-2 runCount3 C
14      *        ThreadName = Thread-0 runCount4 A
15      *        ThreadName = Thread-1 runCount5 B
16      *        ThreadName = Thread-2 runCount6 C
17      *        ThreadName = Thread-0 runCount7 A
18      *        ThreadName = Thread-1 runCount8 B
19      *        ThreadName = Thread-2 runCount9 C
20      *
21      *        可以看到第一個運行的是a線程,因為a線程構造參數showNumPosition正好就是初始的addNumber%3的值
22      *        此時運行代碼后輸出:ThreadName = Thread-0 runCount1 A
23      *        全局addNumber修改為2,a線程中的printCount變成1,當A線程再次執行循環時,進入else代碼塊,線程等待
24      *        
25      *        此時如果時線程c拿到鎖,則線程c會進入else塊,線程等待,然后線程b拿到鎖,由於當前線程a修改了全局addNumber,
26      *        所有線程b在進入循環判斷時,構造參數showNumPosition正好就是初始的addNumber%3的值
27      *        此時運行代碼后輸出:ThreadName = Thread-1 runCount2 B
28      *        並喚醒其他線程,此時a和c線程被喚醒,爭搶鎖
29      *        全局addNumber修改為3,b線程中的printCount變成1,當c線程再次執行循環時,進入else代碼塊,線程等待
30      *        
31      *        此時如果是a線程獲得鎖,則會進入else塊,線程等待,然后c線程拿到鎖,由於當前線程b修改了全局addNumber,
32      *        所有線程c在進入循環判斷時,構造參數showNumPosition正好就是初始的addNumber%3的值
33      *        此時運行代碼后輸出:ThreadName = Thread-2 runCount3 C
34      *        並喚醒其他線程,此時a和b線程被喚醒,爭搶鎖
35      *        全局addNumber修改為4,c線程中的printCount變成1,當c線程再次執行循環時,進入else代碼塊,線程等待
36      *        
37      *        以此類推,當線程中的私有變量printCount為3后,線程退出循環。
38      */
39     public static void main(String[] args) {
40         Object lock = new Object();
41         MyThread a = new MyThread(lock, "A", 1);
42         MyThread b = new MyThread(lock, "B", 2);
43         MyThread c = new MyThread(lock, "C", 0);
44         a.start();
45         b.start();
46         c.start();
47     }
48 }

 


免責聲明!

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



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