A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lxww 中级黑马   /  2013-3-19 21:48  /  1346 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 kingdom_202 于 2013-3-19 22:49 编辑

class Test1 {

public static void main(String[] args) {
  final Show s = new Show();
  
  new Thread(){
   public void run() {
    for(int i=1;i<=3;i++){
     try {
      s.show1();
     } catch(Exception e) {
      e.printStackTrace();
     }
    }
   }
  }.start();
  
  new Thread(){
   public void run() {
    for(int i=1;i<=3;i++){
     try {
      s.show1();
     } catch(Exception e) {
      e.printStackTrace();
     }
    }
   }
  }.start();
  
  new Thread(){
   public void run() {
    for(int i=1;i<=3;i++){
     try {
      s.show1();
     } catch(Exception e) {
      e.printStackTrace();
     }
    }
   }
  }.start();
}
  
}
class Show {
private int a = 1;
public synchronized void show1()throws Exception {   
  if (a!= 1){
   wait();
  }
  System.out.print("我");
  System.out.print("爱");
  System.out.print("你");  
  System.out.print("\r\n");
  a = 2;  
  notify();   
}

public synchronized void show2() throws Exception {
  if(a != 2){
   wait();
  }
  System.out.print("I");
  System.out.print("LOVE");
  System.out.print("YOU");
  System.out.print("\r\n");
  a = 3;   
  notify();   
}

public synchronized void show3() throws Exception {
  if (a != 3){  
   wait();
  }
  System.out.print("I");
  System.out.print("LIKE");
  System.out.print("YOU");
  System.out.print("\r\n");
  a = 1;   
  notify();   
}

}

以上代码。如果我开两个进程的时候。可以正常打印。为什么开三个进程就不行了、运行不下去。只能打印第一个。急!急!急!

点评

如果问题已经解决,请将分类改为“已解决”,谢谢  发表于 2013-3-19 22:47

评分

参与人数 1技术分 +1 收起 理由
猫腻 + 1

查看全部评分

3 个回复

倒序浏览
  1. class Demo1_Notify {
  2.        
  3.         public static void main(String[] args) {
  4.                 final Printer p = new Printer();
  5.                
  6.                 new Thread(){
  7.                         public void run() {
  8.                                 while(true)
  9.                                         try {
  10.                                                 p.print1();
  11.                                         } catch(Exception e) {
  12.                                                 e.printStackTrace();       
  13.                                         }
  14.                         }       
  15.                 }.start();
  16.                
  17.                 new Thread(){
  18.                         public void run() {
  19.                                 for(;;)
  20.                                         try {
  21.                                                 p.print2();
  22.                                         } catch(Exception e) {
  23.                                                 e.printStackTrace();       
  24.                                         }
  25.                         }       
  26.                 }.start();
  27.                
  28.                 new Thread(){
  29.                         public void run() {
  30.                                 for(;;)
  31.                                         try {
  32.                                                 p.print3();
  33.                                         } catch(Exception e) {
  34.                                                 e.printStackTrace();       
  35.                                         }
  36.                         }       
  37.                 }.start();
  38.         }
  39.                
  40. }

  41. class Printer {
  42.         private int flag = 1;        // 创建一个标记变量, 代表目前应该执行哪个方法

  43.         public synchronized void print1() throws Exception {                       
  44.                 while (flag != 1)        // 执行之前判断, 如果刚刚执行过, 就等待
  45.                         wait();
  46.                 System.out.print("传");       
  47.                 System.out.print("智");       
  48.                 System.out.print("播");       
  49.                 System.out.print("客");       
  50.                 System.out.print("\r\n");       
  51.                 flag = 2;                        // 1执行后轮到2了
  52.                 notifyAll();                        // 执行之后通知另外一个线程
  53.         }
  54.        
  55.         public synchronized void print2() throws Exception {
  56.                 while (flag != 2)        // 执行之前判断, 如果刚刚执行过, 就等待
  57.                         wait();
  58.                 System.out.print("黑");       
  59.                 System.out.print("马");       
  60.                 System.out.print("程");       
  61.                 System.out.print("序");       
  62.                 System.out.print("员");       
  63.                 System.out.print("\r\n");
  64.                 flag = 3;                        // 2结束后又应该回到1
  65.                 notifyAll();                        // 执行之后通知另外一个线程
  66.         }
  67.        
  68.         public synchronized void print3() throws Exception {
  69.                 while (flag != 3)               
  70.                         wait();
  71.                 System.out.print("i");       
  72.                 System.out.print("t");       
  73.                 System.out.print("c");       
  74.                 System.out.print("a");       
  75.                 System.out.print("s");       
  76.                 System.out.print("t");       
  77.                 System.out.print("\r\n");
  78.                 flag = 1;                       
  79.                 notifyAll();                       
  80.         }
  81.        
  82. }
复制代码
答案见代码说明

评分

参与人数 1技术分 +2 收起 理由
猫腻 + 2

查看全部评分

回复 使用道具 举报
本帖最后由 刘凯 于 2013-3-19 22:25 编辑

楼主没有发现,你的三个线程一直都是在调用的show1()方法么, 跟本就没有调用show2()  show3()  
当然在第一个线程执行完毕后 a=2
第一个线程循环过来也wait了 notify()了下 由于还没有释放同步锁
所以后边两个线程很可能还没有运行show方法 所以都还没有wait  也就是说 notify()没有唤醒任何线程
这时 第一个线程for循环过来也wait了
其他俩线程得到了执行权,线程if(a!=1) 成立 也都wait了


三个线程都wait了 呀  死锁了呀亲

把后边的两个run方法里的show改了 就好了

评分

参与人数 1技术分 +1 收起 理由
猫腻 + 1

查看全部评分

回复 使用道具 举报
杨博 发表于 2013-3-19 21:52
答案见代码说明

写的太好了。我下去运行了下。很好。非常感谢!呵呵
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马