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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郑传庆 中级黑马   /  2012-6-13 16:33  /  1856 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

如果我程序调用wait()方法的时候就会报java.lang.IllegalMonitorStateException,这个异常,wait()不是让线程等待的吗?而与之想对应的有notify()唤醒等待的线程和唤醒全部的线程notifyAll()方法,我也同样掉用了。为什么还是报错。是不是我用的方式错误了?

class A{
synchronized void ThreadB(B b){
  String name = Thread.currentThread().getName();
  System.out.println(name+"  entered A.ThreadA");
  try {
   Thread.sleep(1000);
  } catch (Exception e) {
   System.out.println("A Interrupted");
  }
  System.out.println(name + " trying to call B.last()");
  b.last();
}
synchronized void last(){
  System.out.println("Inside  A.last");
  
}
}


class B {
synchronized void ThreadA(A a) {
  String name = Thread.currentThread().getName();
  System.out.println(name + "  entered B.ThreadB");
  try {
   Thread.sleep(1000);
  } catch (Exception e) {
   System.out.println("B Interrupted");
  }
  System.out.println(name + " trying to call A.last()");
  a.last();
}
synchronized void last() {
  System.out.println("Inside  A.last");
}
}



class Deadlock implements Runnable {
A a = new A();
B b = new B();
Deadlock() {
  Thread t = new Thread(this, "RacingThread");
  t.start();
}
@Override
public void run() {
  b.ThreadA(a);
  try {
   
//   wait();////这个方法不是等待线程吗?为什么我写这行代码就会报错
  } catch (Exception e) {
   
   e.printStackTrace();
  }
//  notify();//这个方法不是唤醒等待的线程吗?
  
  Thread.currentThread().setName("线程名称:");
  a.ThreadB(b);
  System.out.println("Bcak in main thread");
}
public static void main(String args[]) {
  new Deadlock();
}
}

6 个回复

倒序浏览
package inShool;

class A {
        synchronized void ThreadB(B b) {
                String name = Thread.currentThread().getName();
                System.out.println(name + "  entered A.ThreadA");
                try {
                        Thread.sleep(1000);
                } catch (Exception e) {
                        System.out.println("A Interrupted");
                }
                System.out.println(name + " trying to call B.last()");
                b.last();
                notify();//你在根据题目设计一下wait 和notify 应该放的位置
        }

        synchronized void last() {
                System.out.println("Inside  A.last");

        }
}

class B {
        synchronized void ThreadA(A a) {
                String name = Thread.currentThread().getName();
                System.out.println(name + "  entered B.ThreadB");
                try {
                        Thread.sleep(1000);
                } catch (Exception e) {
                        System.out.println("B Interrupted");
                }
                System.out.println(name + " trying to call A.last()");
                a.last();
        }

        synchronized void last() {
                System.out.println("Inside  A.last");
        }
}

class Deadlock implements Runnable {
        A a = new A();
        B b = new B();

        Deadlock() {
                Thread t = new Thread(this, "RacingThread");
                t.start();
        }

        @Override
        public void run() {
                b.ThreadA(a);
                try {

                         wait();////这个方法不是等待线程吗?为什么我写这行代码就会报错
                } catch (Exception e) {

                        System.out.println("waitting erro");
                }
                 //这个方法不是唤醒等待的线程吗?
                 //你在这里是同一个方法下怎么能自己唤醒自己呢?
                 //我可以理解你的想法,想用t来控制它们达到同步目的;
                 //修改了下程序,把notify放在外面;

                Thread.currentThread().setName("线程名称:");
                a.ThreadB(b);
                System.out.println("Bcak in main thread");
        }

        public static void main(String args[]) {
                new Deadlock();
        }
}

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
问题是没有锁。
这种情况你应该去查API,在Object类中对wait()方法有这样的介绍:
当前线程必须拥有此对象监视器(也就是锁)。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。
老毕视频里有讲到啊。

抛出:
IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。
InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断

看到不认识的异常,就去找到抛出异常的地方,然后去查API一般都能找到原因。
还有个方法可以解决问题。百度之,谷歌之

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 给分之~~

查看全部评分

回复 使用道具 举报
伊文龙 发表于 2012-6-13 20:17
问题是没有锁。
这种情况你应该去查API,在Object类中对wait()方法有这样的介绍:
当前线程必须拥有此对象 ...

要上锁啊,同步我还没怎么用过。Object有介绍我去看看,谢谢了哈
回复 使用道具 举报
你的代码一直就一个线程,也谈不上同步啊。
而起A  B类的对象都是用本类对象当锁。就是同步了也不行啊。

老毕说,线程同步出现问题,看两个方面,第一是否有两个以上的线程同步,第二,是不是用的同一把锁。
回复 使用道具 举报
郑传庆 发表于 2012-6-13 20:23
要上锁啊,同步我还没怎么用过。Object有介绍我去看看,谢谢了哈

嘿嘿,客气哈。老毕同步的视频你看了就会很清楚了。
回复 使用道具 举报
伊文龙 发表于 2012-6-13 20:40
嘿嘿,客气哈。老毕同步的视频你看了就会很清楚了。

有吗?在哪能找到?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马