最代码广告位
MrZive的gravatar头像
MrZive2019-01-11 20:18:16

关于java synchronized 锁的问题

class TT implements Runnable{
	@Override
	public void run() {
		Integer apple=new Integer(10);
		synchronized (apple) {//与while语句互换后就没事
			while(true){
				if(apple==0){
					try {
						apple.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				apple--;
				System.out.println(apple);
			}
		}
	}
}

线程运行后会报java.lang.IllegalMonitorStateException,一直想不明白为什么会报错,debug后,发现apple.wait后,线程没暂停,继续循环到synchronized再次获取锁才报的错,如果synchronized与while语句互换后就没问题,这又是为什么呢???

所有回答列表(11)
genmon5214的gravatar头像
genmon5214 LV52019年3月29日

没改前,synchronized (apple)锁在循环外,而你循环中调用了wait()方法,它在同步代码块或者同步函数中被调用是会释放锁对象的,调用sleep方法不会.当第一次循环结束后,此次锁住的对象就被释放了,当你下一次循环时,对象就没有被锁住.

而你改后,将synchronized (apple)锁放在循环内,这样它每次循环时,即便是调用了wait()方法释放对象,也会被再次锁住.

评论(0)最佳答案
丶右转的gravatar头像
丶右转 LV92019年1月14日

顶顶顶顶顶顶顶顶顶

hqblyq的gravatar头像
hqblyq LV22019年1月14日

顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶

13836800381的gravatar头像
13836800381 LV62019年1月15日

挺好

hr4370913的gravatar头像
hr4370913 LV82019年1月16日

挺好的

张丨丨丨丨丨的gravatar头像
张丨丨丨丨丨2019年1月21日

不知道

JustLikebongbongbong的gravatar头像
JustLikebongbongbong LV112019年1月22日

当执行到apple--后,你的synchrod(apple)锁对象发生变化,导致你的锁消失,而wait()方法不在锁中就会报java.lang.IllegalMonitorStateException

我要很多的牛币的gravatar头像
我要很多的牛币 LV42019年1月24日

0

宾克斯的美酒的gravatar头像
宾克斯的美酒 LV102019年2月12日

欢乐锁,悲观锁

MrZive的gravatar头像
MrZive LV62019年5月31日

谢谢大家的回答

小小神的gravatar头像
小小神 LV42019年10月17日

弄清楚该问题前先了解两个知识点:

1.apple--后apple指向新对象(可以打印apple的hashcode校验)

2.apple.wait()释放对象锁,如果对象没有锁会报java.lang.IllegalMonitorStateException错误

所以:

先锁后循环:锁住apple(apple=10)对象后在while中当apple指向新对象(apple=0)时,尝试去释放锁时失败;

先循环后锁:遍历过程中对每个apple对象加锁,这样就可以释放锁了;

顶部客服微信二维码底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友