关于java多线程中出现IllegalMonitorStateException异常的理解

写在前面

今天在练习多线程中的wait()、notify()方法的时候,出现了java.lang.IllegalMonitorStateException异常,在自己一番挣扎之下,终于解决了此Bug。。。。

当然在此我们提前需要知道,wait()和notify()方法的作用地点和环境:

  1. 相同点:
    两个方法都是Object类的方法,想在程序中对其两者进行的使用的时候,必须得用在synchronized(obj){}里面

  2. 区别:
    wait()方法是用来让该线程进行等待的,而notify()是用来唤醒正在等待的线程,另外,wait()方法释放锁,notify()方法不释放锁。

任务需求

要求将数字从1-26和字母A-Z依次进行打印

代码如下:

package cn.yang.Thread;

public class Wait {

    public static void main(String[] args) {

        //实现了Runnable接口的数字的类
        N n = new N();
        //实现了Runnable接口的打印字母类
        E e = new E();

        //创建线程
        Thread thread = new Thread(n,"数字");
        Thread thread1 = new Thread(e,"英文");

        /**
         *   将线程实现传参------两个实现类中分别定义了Thread属性,为其进行设置
         *      方便其使用notify()的时候唤醒另一个线程
         */
        n.thread = thread1;
        e.thread = thread;

        //开启线程
        thread1.start();
        thread.start();
    }
}

/**
 * 打印数字的类
 */

class N implements Runnable{

    public Thread thread = null;

    @Override
    public void run() {
        synchronized (this){
            for (int i = 1;i <= 26;i++){
                System.out.println(i);
                //唤醒打印英文的线程
                thread.notify();
                //同时让自己处于等待
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

/**
 * 打印英文字母的类
 */

class E implements Runnable{

    public Thread thread = null;

    @Override
    public void run() {

        synchronized (this){
            for (char c = 'A';c <= 'Z';c++){

                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(c);

                //唤醒打印数字的
                thread.notify();
            }
        }

    }
}

但是结果很不幸,出现了如下的异常:

不管采用怎么样的方法,都没能将其解决,最后便去看了javaDoc文档,才知道其原因具体出在哪,下面是解决方法:

解决:

下面是javaDoc文档对该异常的解释:

Thrown to indicate that a thread has attempted to wait on an object’s monitor or to notify other threads waiting on an object’s monitor without owning the specified monitor.

翻译过来其汉语意思就是:

也就是当前的线程不是此对象监视器(锁的对象)的所有者。也就是要在当前线程锁定对象,才能用锁定的对象此行这些方法,需要用到synchronized
锁定什么对象就用什么对象来执行 notify(),
notifyAll(),wait(), wait(long), wait(long,
int)操作
否则就会报IllegalMonitorStateException

也就是说,当你使用synchronized(obj)对该线程进行加锁的时候,那么你在用wait()和notify()方法的时候,一定需要的是在synchronized里面的obj进行该操作,不然会报异常

总结:

线程操作的wait()、notify()、notifyAll()只能在同步控制方法或同步控制块内调用
如果在非同步控制方法或控制块里调用,程序能通过编译,但运行的时候,将得到 IllegalMonitorStateException
异常,并伴随着一些含糊信息,比如 ‘当前线程不是拥有者’。 其实异常的含义是
调用wait()、notify()、notifyAll()的任务在调用这些方法前必须 ‘拥有’(获取)对象的锁。”

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值