黑马程序员技术交流社区

标题: 此程序错误原因求解释 [打印本页]

作者: 付左军    时间: 2012-5-5 16:34
标题: 此程序错误原因求解释
  1. class Res
  2. {
  3.         String name;
  4.         String sex;
  5. }
  6. class Input implements Runnable
  7. {        private Res r;
  8.         Object obj=new Object();
  9.         Input (Res r)
  10.         {
  11.                 this.r=r;
  12.         }
  13.         public void run()
  14.         {
  15.                 int x=0
  16.                 while(true)
  17.                 {
  18.                         synchronized(obj)
  19.                         {
  20.                                 if(x==0)
  21.                                 {
  22.                                 r.name="jack";
  23.                                 r.sex="man";
  24.                                 }
  25.                                 else
  26.                                 {
  27.                                 r.name="lili";
  28.                                 r.sex="nv";
  29.                                 }
  30.                                 x=(x+1)%2;
  31.                         }
  32.                 }
  33.         }
  34. }
  35. class Output implements Runnable//另一线程
  36. {       
  37.         private Res r;
  38.         Object obj=new Object();
  39.         Output(Res r)
  40.         {
  41.                 this.r=r;
  42.         }
  43.         public void run()
  44.         {
  45.                 while (true)
  46.                 {
  47.                         synchronized(obj)
  48.                         {
  49.                         System.out.println(r.name+"...."+r.sex);
  50.                         }
  51.                 }       
  52.         }
  53. }

  54. class InputOutputDemo
  55. {
  56.         public static void main(String [] args)
  57.         {
  58.                 Res r=new Res();
  59.                 Input in=new Input(r);
  60.                 Output.out=new Output(r);
  61.                 Thread t1=new Thread (in);
  62.                 Thread t2=new Thread (out);
  63.                 t1.start();
  64.                 t2.start();
  65.         }
  66. }       
复制代码

作者: 贾联国    时间: 2012-5-5 16:46
主要就是不能多线程的互访通讯,synchronized(obj)里面的同步对象不合适,每个线程都new了obj,不如用主函数里的 r 比较好:
修改的代码如下:


public class InputOutputDemo1 {
        public static void main(String [] args)

    {

            Res r=new Res();

            Input in=new Input(r);

            Output out=new Output(r);

            Thread t1=new Thread (in);

            Thread t2=new Thread (out);

            t1.start();

            t2.start();

    }

}
class Res

{

        String name;

        String sex;

}

class Input implements Runnable

{        private Res r;

        Object obj=new Object();

        Input (Res r)

        {

                this.r=r;

        }

        public void run()

        {

                int x=0;

                while(true)

                {

                        synchronized(r) //为了同步用r
                        {

                                if(x==0)

                                {

                                r.name="jack";

                                r.sex="man";

                                }

                                else

                                {

                                r.name="lili";

                                r.sex="nv";

                                }

                                x=(x+1)%2;

                        }

                }

        }

}

class Output implements Runnable//另一线程

{        

        private Res r;

        Object obj=new Object();

        Output(Res r)

        {

                this.r=r;

        }

        public void run()

        {

                while (true)

                {

                        synchronized(r) //这里也必须用 r 才能同步
                        {

                        System.out.println(r.name+"...."+r.sex);

                        }

                }        

        }

}



作者: 徐慧书    时间: 2012-5-5 17:22
程序中的两个小问题: 第15行, x = 0 少了分号  第61行61.          Output.out=new Output(r);    Output out 中间不应用.
楼主是想实现互斥机制吧,而程序中对obj进行控制,obj在程序中属于各自的成员变量,并且不同的,仅仅名字相同而已,这样一来 synchronized(obj) 这条语句也就没有人热意义了,所谓互斥,就是对同一对象,有多个线程要进行访问,为了防止死锁和错误(会出现严重问题如机票购票系统),而对该对象进行控制,以保证在任一时刻,有且至多有一个线程在访问,显然你程序中这个对象应该是 r 了,那么应该是将r传入, 然后synchronized(r)  。
而楼主程序的目的是什么呢?  个人推测,应该是res 轮番变化,即 jack....man   lili....nv 吧,但是这样改后程序还是无法达到要求的。 希望楼主明确,再进一步分析解决这个问题




作者: 崔仁军    时间: 2012-5-5 17:24
同学你的代码没有什么大错误   只是有些粗心  没注意到    红色表示你出错的地方   其实写程序就是要特别的小心   有时候就是一个分号的问题   而花费大量的时间去检查       我也遇到过这样的事     所以我现在学会了细心 的习惯      
class Res

{

        String name;

        String sex;

}

class Input implements Runnable

{        private Res r;

        Object obj=new Object();

        Input (Res r)

        {

                this.r=r;

        }

        public void run()

        {

                int x=0;    // 此处少了一个分号

                while(true)

                {

                        synchronized(obj)

                        {

                                if(x==0)

                                {

                                r.name="jack";

                                r.sex="man";

                                }

                                else

                                {

                                r.name="lili";

                                r.sex="nv";

                                }
                                x=(x+1)%2;

                        }

                }

        }

}

class Output implements Runnable//另一线程

{        
        private Res r;

        Object obj=new Object();

        Output(Res r)

        {

                this.r=r;

        }

        public void run()

        {

                while (true)

                {

                        synchronized(obj)

                        {

                        System.out.println(r.name+"...."+r.sex);

                        }

                }        
        }

}


public class InputOutputDemo

{

        public static void main(String [] args)

        {

                Res r=new Res();

                Input in=new Input(r);

                Output out=new Output(r);    // 同学你的此处多了一个点 你的(Output.out=new Output(r);)


                Thread t1=new Thread (in);

                Thread t2=new Thread (out);

                t1.start();

                t2.start();

        }

}        

作者: 黑马张立国    时间: 2012-5-5 17:33
建议楼主看毕老师的 多线程(多线程同步代码块)视频
引用毕老师的话 “火车上的卫生间-- 经典”
同步的前提:
1.必须要有两个或多个线程。
2.必须是多个线程使用同一个锁。
建议楼主学习视频时做笔记(我刚学习时没做笔记,结果后来学的多忘的多,不得不复习)
也可能楼主会,但马虎了   
作者: 谭景宾    时间: 2012-5-5 17:34
以上问题解决后,在while循环里判断循环的次数,解决死循环问题后,即可。。。。
作者: 袁錦泰    时间: 2012-5-6 00:29
上面的同学已经说明的很详细了,我只针对你程序对你强调一点.
同步需要满足两个条件:
1.操作两条或两条以上线程
2.多个线程使用同一个锁
你的程序违背了第二个原则,你分别在两个线程中创建对象,不太合适.
所以你需要重新对锁进行选择,这里你会发现无论那条线程都在对同一个对象进行操作,那就是Res r=new Res();
所以你可以将其引用当做锁来进行同步.
再次强调:需要挑选多条线程共同使用的对象作为锁,也就是必须唯一.




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2