java三線程循環有序打印ABC

迅雷筆試題:java

編寫一個程序,開啓3個線程,這3個線程的ID分別爲A、B、C,每一個線程將本身的ID在屏幕上打印10遍,要求輸出結果必須按ABC的順序顯示;如:ABCABC….依次遞推。ide

解決思路:每一個線程運行時先檢查他依賴的線程是否已完成工做,線程B依賴線程A的完成,線程C依賴線程B和線程A的完成,線程A依賴線程C的完成。若是當前線程依賴的線程沒有執行完,則阻塞當前線程直到條件知足再執行。spa

Condition.await()會使當前線程暫時阻塞,並釋放ReentrantLock鎖.線程

Condition.signalAll()會通知激活Condition.await()而阻塞的線程,這時被激活的線程就會繼續檢查(經過while循環))是否知足條件,若是知足並且再次得到ReentrantLock鎖就能繼續運行,不然繼續等待。code

 

 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.ReentrantLock;
 3 
 4 public class ThreadDemo implements Runnable {
 5 
 6     private ReentrantLock lock = new ReentrantLock();
 7     private Condition condition = lock.newCondition();
 8     //標記線程A的狀態,true爲剛執行完。爲何要兩個變量?由於只使用一個變量,當線程A執行完後,a爲true,B線程就會不停執行
 9     //因此線程B執行要執行必須知足a==true&&a2==true
10     private volatile Boolean a = false, a2 = false;
11     //標記線程B的狀態,true爲剛執行完。
12     private volatile Boolean b = false;
13     //標記線程C的狀態,true爲剛執行完。
14     private volatile Boolean c = true;
15 
16     @Override
17     public void run() {
18         String name = Thread.currentThread().getName();
19         lock.lock();
20         //進入臨界區
21         try {
22             for (int i = 0; i < 10; i++) {
23                 if (name.equals("B")) {
24                     //只有a和a2同時爲true時纔打印B,不然阻塞當前線程
25                     while (!a || !a2) {
26                         condition.await();//條件不知足,暫時阻塞線程,暫時釋放lock
27                     }
28                     b = true;
29                     a2 = false;
30                 } else if (name.equals("C")) {
31                     while (!a || !b) {
32                         condition.await();
33                     }
34                     c = true;
35                     b = false;
36                 } else if (name.equals("A")) {
37                     while (!c) {
38                         condition.await();
39                     }
40                     a = true;
41                     a2 = true;
42                     b = false;
43                     c = false;
44                 }
45                 System.out.print(name);
46                 condition.signalAll();//通知正在等待的線程,此時有可能已經知足條件
47             }
48         } catch (InterruptedException e) {
49             e.printStackTrace();
50         } finally {
51             lock.unlock();// 記得要釋放鎖
52         }
53     }
54 
55     public static void main(String[] args) throws InterruptedException {
56         ThreadDemo task = new ThreadDemo();
57         Thread thread1 = new Thread(task);
58         Thread thread2 = new Thread(task);
59         Thread thread3 = new Thread(task);
60         thread1.setName("A");
61         thread2.setName("B");
62         thread3.setName("C");
63         thread1.start();
64         thread2.start();
65         thread3.start();
66     }
67 
68 }

 下面是更簡單的實現方法:blog

 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.ReentrantLock;
 3 
 4 public class ThreadDemo implements Runnable {
 5 
 6     private ReentrantLock lock = new ReentrantLock();
 7     private Condition condition = lock.newCondition();
 8     private int state = 0;
 9 
10     @Override
11     public void run() {
12         String name = Thread.currentThread().getName();
13         lock.lock();
14         // 進入臨界區
15         try {
16             for (int i = 0; i < 10; i++) {
17                 if (name.equals("B")) {
18                     // 只有a和a2同時爲true時纔打印B,不然阻塞當前線程
19                     while (state % 3 != 1) {
20                         condition.await();// 條件不知足,暫時阻塞線程,暫時釋放lock
21                     }
22                 } else if (name.equals("C")) {
23                     while (state % 3 != 2) {
24                         condition.await();
25                     }
26                 } else if (name.equals("A")) {
27                     while (state % 3 != 0) {
28                         condition.await();
29                     }
30                 }
31                 state++;
32                 System.out.print(name);
33                 condition.signalAll();// 通知正在等待的線程,此時有可能已經知足條件
34             }
35         } catch (InterruptedException e) {
36             e.printStackTrace();
37         } finally {
38             lock.unlock();// 記得要釋放鎖
39         }
40     }
41 
42     public static void main(String[] args) throws InterruptedException {
43         ThreadDemo task = new ThreadDemo();
44         Thread thread1 = new Thread(task);
45         Thread thread2 = new Thread(task);
46         Thread thread3 = new Thread(task);
47         thread1.setName("A");
48         thread2.setName("B");
49         thread3.setName("C");
50         thread1.start();
51         thread2.start();
52         thread3.start();
53     }
54 
55 }
相關文章
相關標籤/搜索