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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Zhang_qian 中级黑马   /  2012-5-21 20:05  /  1775 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Exercise3 {
        public static void main(String[] args) {
                final Printer p=new Printer();
                new Thread(){
                        public void run()
                        {
                                for(int i=0;i<5;i++)
                                        p.print1();
                               
                        }
                       
                }.start();
                new Thread(){
                        public void run()
                        {
                                for(int i=0;i<5;i++)
                                        p.print2();
                               
                        }
                       
                }.start();

        }

}
class Printer
{
        private int turn=1;
        public synchronized void print1()
        {
                if(turn!=1)
                        try {
                                this.wait();
                        } catch (InterruptedException e) {
                               
                                e.printStackTrace();
                        }
                else
                        System.out.println("A");
                turn=2;
                this.notify();
        }
        public synchronized void print2()
        {
                if(turn!=2)
                        try {
                                this.wait();
                        } catch (InterruptedException e) {
                               
                                e.printStackTrace();
                        }
                else
                    System.out.println("B");
                turn=1;
                this.notify();
        }
}这里为什么只打印了一次A,B???不明白,请高手帮忙讲解一下,谢谢!

4 个回复

正序浏览
云惟桉 发表于 2012-5-21 20:53
楼上的兄弟已经把问题指出来了。就是唤醒的部分。我的解释在注释里。
1、初始时 turn=1; 那么打印了一次 A  ...

谢谢讲解!
回复 使用道具 举报
楼主可以把print1()和print2()写到一个方法中,就不会出现争用数据导致的并发问题
回复 使用道具 举报
  1. class Printer
  2. {
  3.         private int turn=1;
  4.         public synchronized void print1()
  5.         {
  6.                 if(turn!=1)  [color=Red]// turn == 2时执行[/color]
  7.                         try {
  8.                                 this.wait();
  9.                         } catch (InterruptedException e) {
  10.                                 
  11.                                 e.printStackTrace();
  12.                         }
  13.                 else   [color=Red]// turn ==1时执行[/color]
  14.                         System.out.println("A");
  15.                 turn=2; [color=Red]//执行完毕,又让turn =2;[/color]
  16.                 this.notify();  [color=Red]//此时又唤醒本方线程 打印 B [/color]
  17.         }
  18.         public synchronized void print2()
  19.         {
  20.                 if(turn!=2)
  21.                         try {
  22.                                 this.wait();
  23.                         } catch (InterruptedException e) {
  24.                                 
  25.                                 e.printStackTrace();
  26.                         }
  27.                 else
  28.                     System.out.println("B");
  29.                 turn=1;
  30.                 this.notify();
  31.         }
  32. }
复制代码
楼上的兄弟已经把问题指出来了。就是唤醒的部分。我的解释在注释里。
1、初始时 turn=1; 那么打印了一次 A 然后 turn =2;
2、判断 turn =2 ;那么等待。
此时执行不到下面的语句,就没有人将该线程唤醒了,因此陷入了无限等待,结果只有AB

我想楼主要实现的是互相唤醒对方线程吧,把代码好好审核一遍,改一遍,就会对错误记忆犹新,不会再犯了。
希望楼主能有所收获!
回复 使用道具 举报
  1. public class Exercise3 {
  2.         public static void main(String[] args) {
  3.                 final Printer p=new Printer();
  4.                 new Thread(){
  5.                         public void run()
  6.                         {
  7.                                 for(int i=0;i<5;i++)
  8.                                         p.print1();
  9.                                 
  10.                         }
  11.                         
  12.                 }.start();
  13.                 new Thread(){
  14.                         public void run()
  15.                         {
  16.                                 for(int i=0;i<5;i++)
  17.                                         p.print2();
  18.                                 
  19.                         }
  20.                         
  21.                 }.start();

  22.         }

  23. }
  24. class Printer
  25. {
  26.         private int turn=1;

  27. //第一次调用这个方法的时候turn =1,顺利执行完一次以后turn=2了然后下面
  28.         public synchronized void print1()
  29.         {
  30.                 if(turn!=1)
  31.                         try {
  32.                                 this.wait();//到这里这个线程就wait住了,你永远执行不到下面的  this.notify();  
  33. //你自己wait又让自己把自己唤醒?他已经wait怎么唤醒自己
  34.                         } catch (InterruptedException e) {
  35.                                 
  36.                                 e.printStackTrace();
  37.                         }
  38.                 else
  39.                         System.out.println("A");
  40.                 turn=2;
  41.                 this.notify();
  42.         }
  43.         public synchronized void print2()
  44.         {
  45.                 if(turn!=2)
  46.                         try {
  47.                                 this.wait();//这里同理
  48.                         } catch (InterruptedException e) {
  49.                                 
  50.                                 e.printStackTrace();
  51.                         }
  52.                 else
  53.                     System.out.println("B");
  54.                 turn=1;
  55.                 this.notify();
  56.         }
  57. }这里为什么只打印了一次A,B???不明白,请高手帮忙讲解一下,谢谢!
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马