迅雷筆試題: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 }