MrZive的gravatar头像
MrZive 2019-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  LV5 2019年3月29日

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

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

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

顶顶顶顶顶顶顶顶顶

hqblyq的gravatar头像
hqblyq  LV2 2019年1月14日

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

13836800381的gravatar头像
13836800381  LV6 2019年1月15日

挺好

hr4370913的gravatar头像
hr4370913  LV8 2019年1月16日

挺好的

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

不知道

JustLikebongbongbong的gravatar头像
JustLikebongbongbong  LV11 2019年1月22日

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

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

0

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

欢乐锁,悲观锁

MrZive的gravatar头像
MrZive  LV6 2019年5月31日

谢谢大家的回答

小小神的gravatar头像
小小神  LV4 2019年10月17日

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

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

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

所以:

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

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

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