线程之间的通信应该注意两个类:

wait();

notify();

题目:子线程循环5次,接着主线程循环10次,接着有回到子线程循环5次,

接着再回到主线程循环10次,如此循环2次,请写出程序。

分析:这里的子线程和主线程在执行的时候都需要保护,即子线程执行的时候,主线程不能打断;主线程在执行的时候子线程不能打断。

注意:这里的数字比较小,但写出的代码应该可以简单修改,就可以执行循环次数大的线程通信。

  • 1-1 一个线程通信的简单例子

   
  1. public class TraditionalThreadConmunication { 
  2.     public static void main(String[] args) { 
  3.         final Business business=new Business(); 
  4.         new Thread( 
  5.                 new Runnable() { 
  6.                     @Override 
  7.                     public void run() { 
  8.                         for(int i=1;i<=2;i++){ 
  9.                             business.sub(i); 
  10.                         } 
  11.                     } 
  12.                 } 
  13.         ).start(); 
  14.          
  15.         for(int i=1;i<=10;i++){ 
  16.             business.main(i); 
  17.         } 
  18.     } 
  19.  
  20. class Business{//将线程访问的资源同步,而不是将线程同步, 
  21.                 //好处:以后交给其他的线程访问,不用考虑线程的同步 
  22.     private boolean bShouldSub=true;//刚开始子线程执行 
  23.     public synchronized void sub(int i){//子线程 
  24.         //此处while和if的效果是一样的,但是while防止伪唤醒,被唤醒时还要进行执行确认 
  25.         while(!bShouldSub){ 
  26.             try { 
  27.                 this.wait();//!bShouldSub,主线程在执行,等待 
  28.             } catch (InterruptedException e) { 
  29.                 e.printStackTrace(); 
  30.             } 
  31.         } 
  32.             for (int j = 1; j <= 5; j++) { 
  33.                 System.out.println("sub thread sequece of "+j+",loop of"+i); 
  34.             } 
  35.             bShouldSub=false
  36.             this.notify();//唤醒主线程 
  37.     } 
  38.      
  39.     public synchronized void main(int i){//主线程 
  40.         while(bShouldSub){ 
  41.             try { 
  42.                 this.wait();//bShouldSub,子线程在执行,等待 
  43.             } catch (InterruptedException e) { 
  44.                 e.printStackTrace(); 
  45.             } 
  46.         } 
  47.         for (int j = 1; j <= 10; j++) { 
  48.             System.out.println("main thread sequece of "+j+",loop of"+i); 
  49.         } 
  50.         bShouldSub=true
  51.         this.notify();//唤醒子线程 
  52.     } 

程序运行的结果如下:

总结:上面的代码的实现了线程之间的通信,而且代码的结构完善,将相关的操作写到一个业务类中class Business{},这样就将线程访问的资源同步(最好这么做),而不是将线程同步,因为当以后需要维护代码,交给其他的线程来访问,自然而然地就实现的同步,而不用再设计线程之间的同步。