黑马程序员技术交流社区

标题: 关于类名.class锁的问题 [打印本页]

作者: 邓利军    时间: 2012-9-27 23:21
标题: 关于类名.class锁的问题
本帖最后由 邓利军 于 2012-9-28 18:41 编辑

问题1:运行结果出错,是什么意思?
问题2:此题能不能用类名.class锁?怎么用?
运行结果如下:
Exception in thread "Thread-0" Mike.....man
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
        at java.lang.Object.notify(Native Method)
        at Input.run(ResourceDemo2.java:46)
        at java.lang.Thread.run(Thread.java:722)
java.lang.IllegalMonitorStateException
        at java.lang.Object.notify(Native Method)
        at Output.run(ResourceDemo2.java:73)
        at java.lang.Thread.run(Thread.java:722)
  1. class  Resource
  2. {
  3.          String name;
  4.          String sex;
  5.          boolean flag=false;
  6. }

  7.       

  8. class Input implements Runnable
  9. {
  10.         Resource r;
  11.         Input(Resource r)
  12.         {
  13.                 this.r=r;
  14.         }
  15.         public void run()
  16.         {
  17.                 int x=0;
  18.                 while(true)
  19.                 {
  20.                          synchronized(Resource.class)//能不能用Resource.class锁呢?
  21.                         {
  22.                                 if(r.flag)
  23.                                 {
  24.                                         //r.wait();
  25.                                         try{r.wait();}catch(InterruptedException e){}
  26.                                 }
  27.                                        
  28.                                 
  29.                                 if(x==0)
  30.                                 {
  31.                                         r.name="Mike";
  32.                                         r.sex="man";
  33.                                 }
  34.                                 else
  35.                                 {
  36.                                         r.name="大红";
  37.                                         r.sex="女";
  38.                                 }
  39.                                 r.flag =true;
  40.                                 r.notify();
  41.                         }
  42.                         x=(x+1)%2;
  43.                 }
  44.         }
  45. }

  46. class Output implements Runnable
  47. {
  48.         Resource r;
  49.         Output(Resource r)
  50.         {
  51.                 this.r=r;
  52.         }
  53.         public void run()
  54.         {
  55.                 while(true)
  56.                 {
  57.                          synchronized(Resource.class)
  58.                         {
  59.                                 if (!r.flag)
  60.                                 {
  61.                                         //r.wait();
  62.                                         try{r.wait();}catch(InterruptedException e){}
  63.                                 }
  64.                                 System.out.println(r.name+"....."+r.sex);
  65.                                 r.flag=false;
  66.                                 r.notify();
  67.                         }
  68.                 }
  69.         }
  70. }

  71. class Demo2
  72. {
  73.         public static void main(String[] args)
  74.         {
  75.                 Resource r=new Resource();
  76.                 Input in=new Input(r);
  77.                 Output out=new Output(r);
  78.                 Thread t1=new Thread(in);
  79.                 Thread t2=new Thread(out);
  80.                 t1.start();
  81.                 t2.start();
  82.         }
  83. }
复制代码

作者: 谭立文    时间: 2012-9-28 00:08
package com.wenfengkeji.heima;
class  Resource
{
         String name;
         String sex;
         boolean flag=false;
}

class Input implements Runnable
{
        Resource r;
        Input(Resource r)
        {
                this.r=r;
        }
        public void run()
        {
                int x=0;
                while(true)
                {
                         synchronized(Resource.class)//能不能用Resource.class锁呢?
                        {
                                if(r.flag)
                                {
                                    try
                                    {
                                            Thread.currentThread().sleep(1000);
                                    }catch(InterruptedException e){
                                            throw new RuntimeException(e);
                                    }
                                }
                                if(x==0)
                                {
                                        r.name="Mike";
                                        r.sex="man";
                                }
                                else
                                {
                                        r.name="大红";
                                        r.sex="女";
                                }
                                r.flag =true;
                        }
                        x=(x+1)%2;
                }
        }
}

class Output implements Runnable
{
        Resource r;
        Output(Resource r)
        {
                this.r=r;
        }
        public void run()
        {
                while(true)
                {
                         synchronized(Resource.class)
                        {
                                if (!r.flag)
                                {
                                         try
                                     {
                                             Thread.currentThread().sleep(1000);
                                     }catch(InterruptedException e){
                                             throw new RuntimeException(e);
                                     }
                                }
                                System.out.println(r.name+"....."+r.sex);
                                r.flag=false;
                        }
                }
        }
}

class Demo2
{
        public static void main(String[] args)
        {
                Resource r=new Resource();
                Input in=new Input(r);
                Output out=new Output(r);
                Thread t1=new Thread(in);
                Thread t2=new Thread(out);
                t1.start();
                t2.start();
        }
}
作者: 刘明月    时间: 2012-9-28 00:19
首先做一下锁的总结:锁首先我会想到线程中用到锁,什么时候用呢,当我要确定线程需要同步时,

当时我做练习的时候也出了不少问题,总结的结果是:锁一定要一样!!!

另外你提到了  类名.class() 知道得到的是什么吗,是该类的字节码,类名不一样,该值也不一样,什么是字节码,你可以暂时将其理解为地址,具体看加强的视频
所以说你的第二个问题是:如果output的锁时Resource.class,你的第二题的答案就是yes


作者: 钢伢仔    时间: 2012-9-28 00:38
顽强探索中!
作者: 叶征东    时间: 2012-9-28 00:57
(1),问题主要在try{r.wait();}catch(InterruptedException e){}中的r.wait();当线程执行到r.wait()时,就会停在这里等待,在你用notify()唤醒它之前,线程不会去获取执行权,也就是说如果你不会唤醒它,它就会在那里不动的.所以最好是用sleep()方法,如sleep(1000);当线程睡了1秒之后,它自己会去获取执行权,在获取到执行权之后,就会执行下面的代码.
(2),可以用
类名.class 锁,就像你代码中那样用就可以了.
一个java文件(里面中只有一个类)通过编译后会产生一个 类名.class 文件,当运行这个程序时,JVM就会将class文件加载进内存中,在内存中就会产生一段二进制码对就这个class文件.        类名.class 代表的就是这段二进制码.     这个类的对象可以有多个,但是这个类在内存中所对就的二进制码是唯一的.     更具体的在学习反射时会接触到到,  也可以先看看java.lang包中的Class类.

作者: 刘明月    时间: 2012-9-28 01:43
刘明月 发表于 2012-9-28 00:19
首先做一下锁的总结:锁首先我会想到线程中用到锁,什么时候用呢,当我要确定线程需要同步时,

当时我做练 ...

更正一下
锁只能是对象,但是类名.class()这个字节码为什么可以作为锁呢,而且什么时候进行使用呢?
先说使用,当在静态方法中出现锁时,因为其中不能出现类的对象,所以通过字节码来识别,


所以楼主的第二个问题的答案应该是false

那运行时为什么会出现异常呢,还是我总结的那个:锁不相同,

如果把两个锁改成  r  就哦了






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