返回信息流程序如下:
```
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?
这是一条镜像帖。来源:北邮人论坛 / java / #64207同步于 2020/8/12
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
【问题】Thread 多线程问题
dongqing
2020/8/12镜像同步10 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
在synchronized中为啥不能改变, synchronized不是同步的吗,锁难道是不能变的?
【 在 oneps 的大作中提到: 】
改变LOCK的值导致释放了锁,基础也太差了
因为指向不同的对象了
【 在 dongqing 的大作中提到: 】
: 在synchronized中为啥不能改变, synchronized不是同步的吗,锁难道是不能变的?
:
: ............
别拿字符串当锁,也别用synchronized关键字了。请用java.util.concurrent.lock.ReentrantLock和ReentrantLock.newCondition()。
多谢暖神和楼上的两位
【 在 nuanyangyang 的大作中提到: 】
: 别拿字符串当锁,也别用synchronized关键字了。请用java.util.concurrent.lock.ReentrantLock和ReentrantLock.newCondition()。
为啥不用Syncronized关键字,底层不是也做了一些优化嘛。
虽然我确实基本不用,感觉reetrantlock既显式又更灵活多变
别拿字符串又是因为啥呀,虽然确实基本没人用,我就是好奇
【 在 nuanyangyang 的大作中提到: 】
: 别拿字符串当锁,也别用synchronized关键字了。请用java.util.concurrent.lock.ReentrantLock和ReentrantLock.newCondition()。
: --
: ............
优化完了还是不如ReentrantLock快,也不如ReentrantLock功能多。
关键是synchronized允许你把任何对象当锁用。这不好。锁就应该用专门的锁来充当。如果你锁“hello”字符串,别的模块也锁“hello”字符串,不就互相干扰了?
Java设计之初给每个对象都加了一个内置锁,认为这样很容易实现同步。但它带来的麻烦比带来的收益更多。现在每个对象都必须有内置锁,有开销,而“优化”只是想办法降低这个开销。另一方面,更严重的,一个对象内部,同步用的锁按理说应该是private的,外面不可以访问;可是现实是,synchronized可以获取任何对象的那把“内置锁”,相当于synchronized获取的锁是public的。用它来同步有被外部恶意(或仅仅是错误的)的代码干扰的风险。
明白了,谢谢解答
【 在 nuanyangyang 的大作中提到: 】
: 优化完了还是不如ReentrantLock快,也不如ReentrantLock功能多。
: 关键是synchronized允许你把任何对象当锁用。这不好。锁就应该用专门的锁来充当。如果你锁“hello”字符串,别的模块也锁“hello”字符串,不就互相干扰了?
: ............
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();
: ............