记录java.lang.IllegalMonitorStateException错误,分析Object中wait()和notify()方法含义

当我们在使用多线程中,有时会抱这个错误:

java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at com.flower.dujiaohao.utils.threadstudy.ThreadStudy.main(ThreadStudy.java:18)
java.lang.IllegalMonitorStateException
	at java.lang.Object.notify(Native Method)
	at com.flower.dujiaohao.utils.threadstudy.ThreadStudy.run(ThreadStudy.java:10)
错误的主要原因为:

违法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象(O)的监控器或者通知其他线程等待该对象(O)的监控器时,抛出该异常。
以上错误贴出对应的代码:

public class ThreadStudy extends Thread{
	
	
	public void run(){
//		synchronized (this) {
//		}
		System.out.println("要执行跑了");
		notify();
	}
	
	public static void main(String[] args) throws Exception{
		ThreadStudy s = new ThreadStudy();
		System.out.println("开始执行了!");
		s.start();
		System.out.println("要等待了!");
		s.wait();
		System.out.println("结束了");
//		synchronized (s) {
//		}
		
		
	}

}

根据错误提示我们看到其中行10和行18有错,也就是对应的方法notify()和s.wait(),为什么呢?根据源码我们能得出结论

* The current thread must own this object's monitor. The thread
     * releases ownership of this monitor and waits until another thread
     * notifies threads waiting on this object's monitor to wake up
     * either through a call to the {@code notify} method or the
     * {@code notifyAll} method. The thread then waits until it can
     * re-obtain ownership of the monitor and resumes execution.
     * <p> 
     * As in the one argument version, interrupts and spurious wakeups are
     * possible, and this method should always be used in a loop:
     * <pre>
     *     synchronized (obj) {
     *         while (<condition does not hold>)
     *             obj.wait();
     *         ... // Perform action appropriate to condition
     *     }
     * </pre>含义:当前线程必须拥有此对象的锁,直到另一个线程通知线程在这个对象锁等待醒来
    public final void wait() throws InterruptedException {
        wait(0);
    }

/**
     * Wakes up a single thread that is waiting on this object's
     * monitor. If any threads are waiting on this object, one of them
     * is chosen to be awakened. The choice is arbitrary and occurs at
     * the discretion of the implementation. A thread waits on an object's
     * monitor by calling one of the {@code wait} methods.
     * <p>
     * <ul>
     * <li>By executing a synchronized instance method of that object.
     * <li>By executing the body of a {@code synchronized} statement
     *     that synchronizes on the object.
     * <li>For objects of type {@code Class,} by executing a
     *     synchronized static method of that class.
     * </ul>
     * <p>【含义:唤醒一个线程正在等待这个对象的锁,前提自己也必须拥有这个锁对象】
    public final native void notify();

那么由此我们可以知道,object类中wait()和notify()方法使用规律

1.当前线程”在调用wait()/notify()时,必须拥有该对象的同步锁

2.使用时要在同步快中使用

好了刚才上面的正确代码没有贴上这里补上:

public class ThreadStudy extends Thread{
	
	
	public void run(){
		synchronized (this) {
			System.out.println("要执行跑了");
			notify();
		}
	}
	
	public static void main(String[] args) throws Exception{
		ThreadStudy s = new ThreadStudy();
		synchronized (s) {
			System.out.println("开始执行了!");
			s.start();
			System.out.println("要等待了!");
			s.wait();
			System.out.println("结束了");
		}
		
		
	}

}

这里抛出一个问题,能说一下这段代码执行的输出顺序吗?为什么呢?可以留言告诉我哦 O(∩_∩)O~

答案:

开始执行了!
要等待了!
要执行跑了
结束了



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值