分享

写两个线程,一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z

 沙门空海 2018-03-06

通过这个例题学到了很多,记录下来便于以后常看,<线程通信>  

[java]  
  1. /* 

  2.  * 写两个线程,一个线程打印1-52,另一个线程打印字母A-Z。打印 顺序为12A34B56C……5152Z> 

  3.  */  

  4. public class Test {  


  5.  public static void main(String[] args) {  

  6.   // TODO Auto-generated method stub  

  7.   Object obj = new Object();  

  8.   Shuzi s = new Shuzi(obj);  

  9.   Zimu z = new Zimu(obj);  

  10.   Thread th1 = new Thread(s);  

  11.   Thread th2 = new Thread(z);  

  12.   th1.start();//数字的线程先运行,数字先执行  

  13.   th2.start();  

  14.   /*th2.start(); 

  15.    * th1.start();字母的线程先运行,则先执行字母 

  16.    */  

  17.  }  

  18. }  


  19. class Shuzi implements Runnable{  

  20.  private Object obj;//声明一个类的引用  

  21.  public Shuzi(Object obj){  

  22.   this.obj = obj; //通过构造器将共享的资源-->对象传进来  

  23.  }  


  24.  @Override  

  25.  public void run() {  

  26.   synchronized(obj){//给共享资源上锁  

  27.    for(int i = 1;i < 53;i++ ){  

  28.  System.out.println(i);  

  29.  if(i % 2 == 0){  

  30.   obj.notifyAll();//唤醒其他线程  


  31.   try {  

  32.    obj.wait();//等待并释放锁  

  33.   } catch (InterruptedException e) {  

  34.    // TODO Auto-generated catch block  

  35.    e.printStackTrace();  

  36.   }  

  37.  }  

  38.    }  

  39.   }  


  40.  }  


  41. }  


  42. class Zimu implements Runnable{  

  43.  private Object obj;  

  44.  public Zimu(Object obj){  

  45.   this.obj = obj;   

  46.  }  


  47.  @Override  

  48.  public void run() {  

  49.   synchronized(obj){  

  50.    for(int i = 0;i < 26;i++ ){  

  51.  System.out.println((char)(i+'A'));  

  52.   obj.notifyAll();//唤醒其他线程  

  53.  try {  

  54.   obj.wait();//释放锁等待  

  55.  } catch (InterruptedException e) {  

  56.   // TODO Auto-generated catch block  

  57.   e.printStackTrace();  

  58.  }  

  59.    }  

  60.   }  


  61.  }  


  62. }  

这是线程间的通信的一个很有代表性的例子。过程如下:

1、创建两个线程实现Runnable接口重写run方法,一个用于打印数字,一个用于打印字母。

2、创建一个测试类,在测试类中创建一个Object类的对象(作为两个线程的共享资源,以便实现线程间的通信),通过各类的构造方法传递过去。

3、在两个类的run方法中都要用synchronized保证同步,即加锁。

4、在数字类中用for循环每打印两个数字就唤醒其他线程,释放锁,进入阻塞状态。

  在字母类中每打印一个字母就唤醒其他线程,释放锁,进入阻塞状态。

在写这个程序的时候有几点要注意的地方:

1、两个线程要使用同一个资源才需相互通信,所以在测试类中创建共享资源,并通过构造方法分别传到各线程类中。

2、两个线程哪个先运行(执行start())哪个就先获得资源并执行

3、在run方法体内写进程间的通信wait()和notifyall()时,一定要先写notifyall()再写wait()。

    原因:当你先写wait()时,本进程也进入休眠状态,再写notifyall()唤醒所有线程时本线程以及其他线程被一块唤醒,竞争同一个资源,就会造成死锁。 所以一定要先唤醒其他线程,再让本线程阻塞!

分享一些技术学习视频教程 https://pan.baidu.com/s/13dbR69NLIEyP1tQyRTl4xw   

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多