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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 傅荣康 黑马帝   /  2011-8-1 20:45  /  2229 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Exercise {
public static void main(String[] args) {
  Exercise ex=new Exercise();
  ex.go();
}
public void go(){
  MyThread mt=new MyThread("one");
  mt.start();
}
}

class MyThread extends Thread{
private String name="";
MyThread(String s){
  name=s;
}
public void run(){
  notwait();  
  System.out.println("finished");
}
public void notwait(){
  while(true){
   try{
    System.out.println("waiting");
    wait();
   }
   catch(InterruptedException e){}
   System.out.println(name);
  }
}
}
这段程序运行后结果为
waiting
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at mypackage.MyThread.notwait(Exercise.java:34)
at mypackage.MyThread.run(Exercise.java:24)
请问导致此异常的具体原因。非常感谢!

评分

参与人数 1技术分 +1 收起 理由
admin + 1 提问要说明白点哦!

查看全部评分

2 个回复

正序浏览
对于Object类提供的wait()notify()、notifyAll()这三个方法必须要由同步监视器对象来调用的,这可以分为两种情况:
1、对于使用synchronized修饰的方法,因为该类的默认实例this就是同步监视器,所以可以在同步方法中直接使用这三个方法[code=java]public synchronized void draw(double drawAmount)
        {
                try
                {
                        //如果flag为假,表明账户中还没有人存钱进去,则取钱方法阻塞
                        if (!flag)
                        {
                                wait();
                        }
                        else
                        {
                                //执行取钱
                                System.out.println(Thread.currentThread().getName() +
                                        " 取钱:" +  drawAmount);
                                balance -= drawAmount;
                                System.out.println("账户余额为:" + balance);
                                //将标识账户是否已有存款的旗标设为false。
                                flag = false;
                                //唤醒其他线程
                                notifyAll();
                        }
                }
                catch (InterruptedException ex)
                {
                        ex.printStackTrace();
                }
        }[/code]2、对于使用synchronized修饰的同步代码块,同步监视器是synchronized后面括号里面的对象,所以必须使用这个对象调用这三个方法:[code=java]public  void draw(double drawAmount)
        {
                synchronized(account)
                        try
                        {
                                //如果flag为假,表明账户中还没有人存钱进去,则取钱方法阻塞
                                if (!flag)
                                {
                                        account.wait();
                                }
                                else
                                {
                                        //执行取钱
                                        System.out.println(Thread.currentThread().getName() +
                                                " 取钱:" +  drawAmount);
                                        balance -= drawAmount;
                                        System.out.println("账户余额为:" + balance);
                                        //将标识账户是否已有存款的旗标设为false。
                                        flag = false;
                                        //唤醒其他线程
                                        account.notifyAll();
                                }
                        }
                        catch (InterruptedException ex)
                        {
                                ex.printStackTrace();
                        }
                }
        }[/code]

评分

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

查看全部评分

回复 使用道具 举报
不知道你的程序要做什么用, 不过IllegalMonitorStateException是因为你的wait()少添加了一个监听,
在wait()改成
  1. synchronized(this)
  2. {
  3.         wait();
  4. }
复制代码
就行了。
myeclipse下右键→Surround With里面有直接加监听的代码。
[ 本帖最后由 李龙 于 2011-08-01  21:27 编辑 ]

评分

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

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马