java多執行緒面試題:三個執行緒順序列印ABC,重複10次
阿新 • • 發佈:2019-01-05
這個面試題,比較經典。有不同的解決思路。有的博文是用Join去實現。我面試的時候也是第一個想到的是用join叫A執行緒等待B執行緒執行完再執行。這樣的思路能實現,但是不好。雖然當時湊合著說服了面試官。先把程式碼貼出來
這個思路比較簡單。三個執行緒。啟動a,列印完A後;啟動b,列印完B後;啟動c。雖然能實現順序列印,但是會之後還會重複建立執行緒。這個面試題當時答的貌似有道理,同時跟面試官說了說多執行緒的知識,面試官還算滿意。回來後一考慮,太Low了。然後自己查資料研究了一下。下邊把正確答案貼出來private Thread aThread,bThread,cThread; @Test public void test1() { aThread=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println("A"); try { bThread.start(); bThread.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); bThread=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println("B"); try { cThread.start(); cThread.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); cThread=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println("C"); } }); aThread.start(); }
public class MyTest1 { private static Boolean flagA=true; private static Boolean flagB=false; private static Boolean flagC=false; public static void main(String[] args) { final Object lock = new Object(); Thread aThread=new Thread(new Runnable() { @Override public void run() { for(int i=0;i<10;) { synchronized (lock) { if (flagA) { //執行緒A執行 System.out.println("A"); flagA=false; flagB=true; flagC=false; lock.notifyAll(); i++; }else { try { lock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }); Thread bThread=new Thread(new Runnable() { @Override public void run() { for(int i=0;i<10;) { synchronized (lock) { if (flagB) { //執行緒執行 System.out.println("B"); flagA=false; flagB=false; flagC=true; lock.notifyAll(); i++; }else { try { lock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }); Thread cThread=new Thread(new Runnable() { @Override public void run() { for(int i=0;i<10;) { synchronized (lock) { if (flagC) { //執行緒執行 System.out.println("C"); flagA=true; flagB=false; flagC=false; lock.notifyAll(); i++; }else { try { lock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }); cThread.start(); bThread.start(); aThread.start(); }
親測通過。沒什麼問題。基本思路就是設定三個boolean變數和一個鎖。flag控制那個執行緒可以走,那個應該停下來。然後在列印後才i++。直到i<10的時候,執行緒停止。
下邊在送一個例項。寫一個多執行緒程式,交替輸出1,2,1,2,1,2......
原理一樣,關鍵程式碼就是public class OutputThread implements Runnable { private int num; private Object lock; public OutputThread(int num, Object lock) { super(); this.num = num; this.lock = lock; } public void run() { try { while(true){ synchronized(lock){ lock.notifyAll(); lock.wait(); System.out.println(num); } } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args){ final Object lock = new Object(); Thread thread1 = new Thread(new OutputThread(1,lock)); Thread thread2 = new Thread(new OutputThread(2, lock)); thread1.start(); thread2.start(); } }
while(true){
synchronized(lock){
lock.notifyAll();
lock.wait();
System.out.println(num);
}
}