当一个线程在同步块内部调用 lock.wait();
后,这个线程会释放对 lock
对象的锁。这意味着其他线程现在有机会获取这个锁并进入那个同步块。
这是 wait()
方法的关键特性之一:它不仅使线程进入等待状态,同时也释放了它持有的锁,从而允许其他线程进入被该锁保护的同步区域。这样,其他线程可以执行它们自己的同步代码块,包括调用 notify()
或 notifyAll()
方法来唤醒等待的线程。
下面是这个过程的一个简化示例:
public class Example {
public static void main(String[] args) {
final Object lock = new Object();
// 线程 1
new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Thread 1 is waiting.");
lock.wait();
System.out.println("Thread 1 is resumed.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
// 线程 2
new Thread(() -> {
synchronized (lock) {
System.out.println("Thread 2 has entered the synchronized block.");
// 可以执行一些操作,甚至可以调用 lock.notify();
}
}).start();
}
}
在这个例子中,当线程 1 调用 lock.wait()
后,它释放了对 lock
的锁。这使线程 2 能够获取锁并进入它的同步块。如果线程 2 决定调用 lock.notify()
,那么它可以唤醒线程 1。然后,线程 1 会尝试重新获取锁,一旦获取成功,它就会从 wait()
调用之后继续执行。
在上述代码示例输出:
-
线程 1 开始执行,进入同步块,打印 “Thread 1 is waiting.”,然后调用
lock.wait()
进入等待状态并释放锁。 -
在 线程 1 等待的同时,线程 2 得以执行,获取锁,进入同步块,打印 “Thread 2 has entered the synchronized block.”。在它的同步块结束后,锁被释放。
-
如果 线程 2 在其同步块中调用了
lock.notify()
,那么 线程 1 可以被唤醒。否则,线程 1 将会继续等待直到有其他线程调用lock.notify()
或lock.notifyAll()
。
示例输出可能如下(假设线程 2 没有调用 notify()
):
Thread 1 is waiting.
Thread 2 has entered the synchronized block.
如果 线程 2 调用了 notify()
,那么 线程 1 将被唤醒并继续执行,输出可能如下:
Thread 1 is waiting.
Thread 2 has entered the synchronized block.
Thread 1 is resumed.