[提问] 不同线程的类如何锁住同一个对象

2018-03-31 18:50:05 +08:00
 kerb15

最近在学习多线程的时候遇到一个问题。

我用不同的线程类分别实例化了一个线程 thread1 和 thread2

thread1 和 thread2 分别在各自的 run 方法中 synchronize 了一个静态对象,然后在 thread1 中调用了 wait 方法,在 thread2 中调用了 notify 方法,发现会报错 java.lang.IllegalMonitorStateException

希望有大佬能够给小弟解答一二,非常感谢!

下面是代码:

public class MyThread extends Thread {

	@Override
	public void run() {
		synchronized (Main.i) {
			while (true) {
				Main.i = Main.i + 1;
				if (Main.i == 2) {
					try {
						Main.i.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
}
public class MyThread2 extends Thread {

	@Override
	public void run() {
		synchronized (Main.i) {
			while (true) {
				if (Main.i==2){
					Main.i.notify();
				}
			}
		}
	}
}
public class Main {

	public static volatile Integer i = 0;

	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		MyThread2 myThread2 = new MyThread2();
		myThread.start();
		myThread2.start();
	}
}
2800 次点击
所在节点    Java
8 条回复
wwqgtxx
2018-03-31 18:57:44 +08:00
你这里 Main.i = Main.i + 1;的时候 i 都已经不是同一个对象了好吧
kerb15
2018-03-31 18:59:11 +08:00
@wwqgtxx 为什么不是同一个对象啊,它不是静态的吗
lhx2008
2018-03-31 19:14:49 +08:00
@kerb15 你下面自己把 main.i 改了,相当于重新新建了一个 main.i,赋值,因为 Integer 是不变对象
iffi
2018-03-31 19:21:45 +08:00
看了下 Integer 是 final。它们不是同一个对象
ahmcscx
2018-03-31 19:22:28 +08:00
用 ReentrantLock
XinLake
2018-03-31 19:52:34 +08:00
我记得官方文档里讲 synchronized 锁对象应该用尽量简单的,像 Object。
Arsenal16
2018-03-31 20:58:07 +08:00
少年手边有《实战 Java 高并发程序设计》嘛?可以参见 2.8.4 错误的加锁这一节。
kerb15
2018-03-31 21:32:52 +08:00
懂了,谢谢大家的热心指导!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/443186

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX