wait()
是让获得对象锁的线程实现等待,会自动释放当前线程占有的对象锁。每个对象(Object
)都拥有对象锁,既然要释放当前线程占有的对象锁并让其进入 WAITING 状态,自然是要操作对应的对象(Object
)而非当前的线程(Thread
)。
类似的问题:为什么 sleep()
方法定义在 Thread
中?
因为 sleep()
是让当前线程暂停执行,不涉及到对象类,也不需要获得对象锁。
以下是一个简单的例子,展示了如何在Java中使用 wait()
和 notify()
方法:
public class WaitNotifyExample {
private int count = 0;
private final Object lock = new Object();
public void increment() {
synchronized (lock) {
while (count == 5) {
try {
// 当前线程等待,直到其他线程调用 lock.notify() 或 lock.notifyAll()
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
count++;
System.out.println("Incremented count to " + count);
// 唤醒可能正在等待的其他线程
lock.notifyAll();
}
}
public void decrement() {
synchronized (lock) {
while (count == 0) {
try {
// 当前线程等待,直到其他线程调用 lock.notify() 或 lock.notifyAll()
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
count--;
System.out.println("Decremented count to " + count);
// 唤醒可能正在等待的其他线程
lock.notifyAll();
}
}
public static void main(String[] args) {
WaitNotifyExample example = new WaitNotifyExample();
// 创建两个线程,一个用于增加计数,一个用于减少计数
Thread incrementThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
example.increment();
try {
Thread.sleep(100); // 模拟一些工作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
});
Thread decrementThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
example.decrement();
try {
Thread.sleep(150); // 模拟一些工作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
});
// 启动线程
incrementThread.start();
decrementThread.start();
}
}
在这个例子中,我们有一个 WaitNotifyExample
类,它有一个 count
变量和两个方法:increment()
和 decrement()
。这两个方法都使用 synchronized
块来同步对 count
变量的访问。当 count
达到某个值时(在这个例子中是5或0),调用 wait()
的线程将等待,直到其他线程调用 notify()
或 notifyAll()
方法。这允许我们实现一个简单的生产者-消费者模型,其中一个线程增加计数,另一个线程减少计数。