能解决下面的问题,基本上就能理解线程互斥与同步了。
子线程循环10次,主线程循环100次,接着子线程循环10,主线程循环100次。如此往复循环50次。
1 package cn.lah.thread; 2 3 public class TraditionalThreadCommunication { 4 5 public static void main(String[] args) { 6 7 final Business business = new Business(); 8 new Thread(new Runnable() { 9 public void run() { 10 for (int i = 1; i <= 50; i++) { 11 business.sub(i); 12 } 13 } 14 }).start(); 15 16 for (int i = 1; i <= 50; i++) { 17 business.main(i); 18 } 19 20 } 21 22 } 23 24 //定义一个业务逻辑类,将线程同步相关的方法归于本类,这种设计可以实现高内聚,并能增强代码的健壮性 25 class Business { 26 27 private boolean beShouldSub = true; 28 29 public synchronized void sub(int i) { 30 while (!beShouldSub) { 31 try { 32 this.wait(); 33 } catch (InterruptedException e) { 34 e.printStackTrace(); 35 } 36 } 37 for (int j = 1; j <= 10; j++) { 38 System.out.println("sub Thread" + j + " loop" + i); 39 } 40 beShouldSub = false; 41 this.notify(); 42 } 43 44 public synchronized void main(int i) { 45 while (beShouldSub) { 46 try { 47 this.wait(); 48 } catch (InterruptedException e) { 49 e.printStackTrace(); 50 } 51 } 52 for (int j = 1; j <= 100; j++) { 53 System.out.println("main Thread" + j + " loop" + i); 54 } 55 beShouldSub = true; 56 this.notify(); 57 } 58 }
另一个类似的面试题:
有ABC三个线程,A线程输出A,B线程输出B,C线程输出C,如此循环往复10次。
解法类似:
1 package cn.lah.thread; 2 3 public class ABCThreadTest { 4 private static ABCThreadCommunication communication = new ABCThreadCommunication(); 5 public static void main(String[] args) { 6 7 new Thread(new Runnable() { 8 9 public void run() { 10 for (int i = 1; i <= 10; i++) { 11 communication.showA(i); 12 } 13 14 } 15 }).start(); 16 17 new Thread(new Runnable() { 18 public void run() { 19 for (int i = 1; i <= 10; i++) { 20 communication.showB(i); 21 } 22 } 23 }).start(); 24 25 new Thread(new Runnable() { 26 27 public void run() { 28 for (int i = 1; i <= 10; i++) { 29 communication.showC(i); 30 } 31 32 } 33 }).start(); 34 35 } 36 37 } 38 39 class ABCThreadCommunication { 40 private boolean beShouldA = true; 41 private boolean beShouldB = false; 42 private boolean beShouldC = false; 43 public synchronized void showA(int i) { 44 while(!beShouldA){ 45 try { 46 this.wait(); 47 } catch (InterruptedException e) { 48 e.printStackTrace(); 49 } 50 } 51 System.out.println("A" + " loop " + i); 52 beShouldA = false; 53 beShouldB = true; 54 this.notifyAll(); 55 } 56 57 public synchronized void showB(int i) { 58 while(!beShouldB){ 59 try { 60 this.wait(); 61 } catch (InterruptedException e) { 62 e.printStackTrace(); 63 } 64 } 65 System.out.println("B" + " loop " + i); 66 beShouldB = false; 67 beShouldC = true; 68 this.notifyAll(); 69 } 70 71 public synchronized void showC(int i) { 72 while(!beShouldC){ 73 try { 74 this.wait(); 75 } catch (InterruptedException e) { 76 e.printStackTrace(); 77 } 78 } 79 System.out.println("C" + " loop " + i); 80 beShouldC = false; 81 beShouldA = true; 82 this.notifyAll(); 83 } 84 }