public class MyVisibility {
private static int count = 0;
private static Object lock = new Object();
public static void main(String[] args) {
new MyVisibility.thread1().start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
new MyVisibility.thread2().start();
}
static class thread1 extends Thread {
int i = 0;
@Override
public void run() {
super.run();
while (true) {
synchronized (lock) {
count++;
System.out.println("Thread one count is " + count);
try {
lock.wait();
System.out.println("i am notified");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count > 5) {
return;
}
}
}
}
static class thread2 extends Thread {
int i = 10;
@Override
public void run() {
super.run();
while (true) {
synchronized (lock) {
count++;
System.out.println("Thead 2 count is " + count);
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count > 10) {
return;
}
}
}
}
}
在上面的代码中,执行时的当前结果:我可以看到lock.notify()仅在while循环结束后才被调用。
我的假设是,由于count.count变量增加后立即调用lock.notify(),因此它应立即通知等待线程恢复执行,而不是在执行线程的第二个线程完成后才等待等待线程恢复,这是什么原因,有人可以纠正我理解上的错误。
谢谢。
您的推论-“我可以看到lock.notify()仅在while循环结束后才被调用”并不完全正确。尝试多次运行,或在线程2的synchronized
块之后放置断点,然后您将看到线程1 “已通知我”正在打印。
摘自notify()
的文档-
被唤醒的线程要等到当前线程放弃对此对象的锁定
在您的情况下,在线程2放弃锁然后线程1获得锁之前,线程2通过进入synchronized
块再次获得锁。