• 关于java.lang.IllegalMonitorStateException异常说明(四)


    1、异常原因及解释

    首先你要了解这个异常为什么会抛出,这个异常会在三种情况下抛出:
    1>当前线程不含有当前对象的锁资源的时候,调用obj.wait()方法;
    2>当前线程不含有当前对象的锁资源的时候,调用obj.notify()方法。
    3>当前线程不含有当前对象的锁资源的时候,调用obj.notifyAll()方法。

    java.lang.IllegalMonitorStateException是在调用object的wait和notify,notifyAll方法的时候可能会出现的异常。 在调用上述三个方法的时候,线程必须获得该对象的对象级别锁,换句话说,出现这个异常的原因是因为,调用wait和notify,notifyAll的对象没有在同步方法(synchronized修饰的方法)或者同步代码块(synchronized(x){})中。

    wait()和notify()方法的调用必须具有内置锁 synchronized(this) 的代码块内或同步方法才能调用,否则就会报该错误。

    如果用了显式锁 Lock 就不要用 wait() 和 notify() 了,它们是两套加锁机制,不能混着用的。

    2、对象级别加锁

    想要获取该对象的对象级别锁,即直接调用Object对象的上述三个方法,也就只有在同步方法或同步代码块中。(同步方法或同步代码块以当前对象this作为同步监视器)。

     3、调用某个对象的wait方法

    如果要调用某个对象的wait方法,那么必须这么调用:

    Object lock = new Object();
     synchronized(lock){
     lock.wait();
     }
    
    如果是
    Object lock = new Object();
    synchronized(lock){
    this.wait();
    }
    报错

    4、举例

     1 package com.asd.reserve.pojo.thread;
     2 
     3 /**
     4  * @author zs
     5  * @date 2019/11/15 14:37
     6  */
     7 public class MyThread31 extends Thread
     8 {
     9     private Object lock;
    10 
    11     public MyThread31(Object lock)
    12     {
    13         this.lock = lock;
    14     }
    15 
    16     public void run() {
    17         ThreadDomain31 td = new ThreadDomain31();
    18         td.testMethod(lock);
    19     }
    20 
    21     public static void main(String[] args)
    22     {
    23         Object lock = new Object();
    24         MyThread31 mt0 = new MyThread31(lock);
    25         MyThread31 mt1 = new MyThread31(lock);
    26         mt0.start();
    27         try {
    28             Thread.sleep(100);
    29         } catch (InterruptedException e) {
    30             e.printStackTrace();
    31         }
    32         mt1.start();
    33     }
    34 }
    35 
    36 package com.asd.reserve.pojo.thread;
    37 
    38 /**
    39  * @author zs
    40  * @date 2019/11/15 14:37
    41  */
    42 public class ThreadDomain31 {
    43     public void testMethod(Object lock)
    44     {
    45         try
    46         {
    47             synchronized (lock) {
    48                 System.out.println(Thread.currentThread().getName() + " Begin wait()");
    49                 //lock.notify();
    50                 //Thread.sleep(1000);
    51                 lock.wait();
    52                 Class<? extends ThreadDomain31> aClass = this.getClass();
    53                 String name = aClass.getName();
    54                 //super.wait();//调用此方法时,就会抛出该异常,因为当前的锁资源是lock。改成synchronized (this)可调用
    55                 System.out.println(Thread.currentThread().getName() + " End wait");
    56                 //lock.notify();
    57             }
    58         }
    59         catch (InterruptedException e)
    60         {
    61             e.printStackTrace();
    62         }
    63     }
    64 }
    如果错过太阳时你流了泪,那你也要错过群星了。
    在所有的矛盾中,要优先解决主要矛盾,其他矛盾也就迎刃而解。
    不要做个笨蛋,为失去的郁郁寡欢,聪明的人,已经找到了解决问题的办法,或正在寻找。
  • 相关阅读:
    JVM命令
    悲观锁与乐观锁
    bean生命周期
    MyBatis面试题
    微服务面试题
    MyCat简介
    十大排序算法
    h5跳转微信公众号关注页面
    Maven项目 配置文件放在resources标记的目录下 却没有打包进target文件
    本机号码一键登录原理与应用
  • 原文地址:https://www.cnblogs.com/szrs/p/11867805.html
Copyright © 2020-2023  润新知