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 }