BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #64207同步于 2020/8/12
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

【问题】Thread 多线程问题

dongqing
2020/8/12镜像同步10 回复
程序如下: ``` public class Demo { public static void main(String[] args){ Thread1 t1 = new Thread1(); Thread2 t2 = new Thread2(); t1.start(); t2.start(); } static class Thread1 extends Thread{ Thread1(){ super("t1"); } @Override public void run() { while (true){ synchronized (LOCK){ while("A".equals(LOCK)){ try { LOCK.wait(500); } catch (InterruptedException e) { e.printStackTrace(); } } LOCK = "A"; System.out.println("A"); LOCK.notify(); } Thread.yield(); } } } static String LOCK = ""; static class Thread2 extends Thread{ Thread2(){ super("t2"); } @Override public void run() { while (true){ synchronized (LOCK){ while("B".equals(LOCK) || "".equals(LOCK)){ try { LOCK.wait(1000); } catch (InterruptedException e) { e.printStackTrace(); } } LOCK = "B"; System.out.println("B"); LOCK.notify(); } Thread.yield(); } } } } ``` 本意是想让线程t1, t2交替输出AB 但是执行时,却报错,提示 Exception in thread "t1" Exception in thread "t2" java.lang.IllegalMonitorStateException at java.lang.Object.notify(Native Method) at Demo$Thread1.run(Demo.java:28) java.lang.IllegalMonitorStateException at java.lang.Object.notify(Native Method) at Demo$Thread2.run(Demo.java:55) 但是wait和notify方法都是再synchronized中执行的,为什么会报IllegalMonitorStateException?
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
oneps机器人#1 · 2020/8/12
改变LOCK的值导致释放了锁,基础也太差了
dongqing机器人#2 · 2020/8/12
在synchronized中为啥不能改变, synchronized不是同步的吗,锁难道是不能变的? 【 在 oneps 的大作中提到: 】 改变LOCK的值导致释放了锁,基础也太差了
xuanyu66机器人#3 · 2020/8/12
因为指向不同的对象了 【 在 dongqing 的大作中提到: 】 : 在synchronized中为啥不能改变, synchronized不是同步的吗,锁难道是不能变的? : : ............
nuanyangyang机器人#4 · 2020/8/12
别拿字符串当锁,也别用synchronized关键字了。请用java.util.concurrent.lock.ReentrantLock和ReentrantLock.newCondition()。
dongqing机器人#5 · 2020/8/12
多谢暖神和楼上的两位 【 在 nuanyangyang 的大作中提到: 】 : 别拿字符串当锁,也别用synchronized关键字了。请用java.util.concurrent.lock.ReentrantLock和ReentrantLock.newCondition()。
xuanyu66机器人#6 · 2020/8/13
为啥不用Syncronized关键字,底层不是也做了一些优化嘛。 虽然我确实基本不用,感觉reetrantlock既显式又更灵活多变 别拿字符串又是因为啥呀,虽然确实基本没人用,我就是好奇 【 在 nuanyangyang 的大作中提到: 】 : 别拿字符串当锁,也别用synchronized关键字了。请用java.util.concurrent.lock.ReentrantLock和ReentrantLock.newCondition()。 : -- : ............
nuanyangyang机器人#7 · 2020/8/13
优化完了还是不如ReentrantLock快,也不如ReentrantLock功能多。 关键是synchronized允许你把任何对象当锁用。这不好。锁就应该用专门的锁来充当。如果你锁“hello”字符串,别的模块也锁“hello”字符串,不就互相干扰了? Java设计之初给每个对象都加了一个内置锁,认为这样很容易实现同步。但它带来的麻烦比带来的收益更多。现在每个对象都必须有内置锁,有开销,而“优化”只是想办法降低这个开销。另一方面,更严重的,一个对象内部,同步用的锁按理说应该是private的,外面不可以访问;可是现实是,synchronized可以获取任何对象的那把“内置锁”,相当于synchronized获取的锁是public的。用它来同步有被外部恶意(或仅仅是错误的)的代码干扰的风险。
xuanyu66机器人#8 · 2020/8/14
明白了,谢谢解答 【 在 nuanyangyang 的大作中提到: 】 : 优化完了还是不如ReentrantLock快,也不如ReentrantLock功能多。 : 关键是synchronized允许你把任何对象当锁用。这不好。锁就应该用专门的锁来充当。如果你锁“hello”字符串,别的模块也锁“hello”字符串,不就互相干扰了? : ............
youxiansheng机器人#9 · 2020/8/14
String类型是不变的,把LOCK赋值A,B等于是用不同的String对象在notify 【 在 dongqing 的大作中提到: 】 : 程序如下: : [md] : ``` : public class Demo { : public static void main(String[] args){ : Thread1 t1 = new Thread1(); : Thread2 t2 = new Thread2(); : t1.start(); : t2.start(); : ............