📅  最后修改于: 2023-12-03 15:01:34.451000             🧑  作者: Mango
在Java中,我们可以使用等待(wait)方法来阻塞一个线程,直到某个条件得到满足。等待通常用于多线程情况下进行同步。
等待方法只能在同步代码块(或同步方法)中调用,它会导致当前线程进入等待状态,并释放锁。等待状态将持续到另一个线程持有相同对象的锁,并通知正在等待的线程调用notify()或notifyAll()方法。
wait方法有两个重载方法:
public final void wait() throws InterruptedException
public final native void wait(long timeout) throws InterruptedException
第一个方法使当前线程一直等待,直到另一个线程调用notify()或notifyAll()方法;第二个方法允许你指定最长等待时间。
public class WaitExample {
public synchronized void waitForSignal() throws InterruptedException {
wait();
}
public synchronized void doNotify() {
notify();
}
}
在这个示例中,我们声明了一个waitForSignal()方法,用于等待另一个线程调用doNotify()方法。注意,这两个方法都是同步的。
使用示例:
WaitExample example = new WaitExample();
new Thread(() -> {
try {
example.waitForSignal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
Thread.sleep(1000); // 模拟一些处理时间
example.doNotify();
这里我们创建了一个WaitExample对象,并使用一个线程调用waitForSignal()方法,此时线程将进入等待状态。然后我们暂停主线程一段时间,之后调用doNotify()方法,这将使waitForSignal()方法继续执行。
另一种等待线程结束的方法是使用join()方法。join()方法会阻塞当前线程,直到被调用线程结束。
join()方法有三个重载方法:
public final void join() throws InterruptedException
public final synchronized void join(long millis) throws InterruptedException
public final synchronized void join(long millis, int nanos) throws InterruptedException
第一个方法会一直等待,直到被调用线程结束。另外两个方法允许你指定最长等待时间。
Thread t = new Thread(() -> {
// 模拟一些处理时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start();
t.join();
System.out.println("线程执行完毕!");
这里我们创建了一个线程t,并使用join()方法阻塞主线程,直到t线程执行完毕。注意,这个示例没有使用同步代码,因为我们只是等待一个简单的线程完成。
CountDownLatch类可以用于等待一组线程完成。当我们想要等待多个线程完成时,使用这个类比使用join()方法更加实用。
CountDownLatch类是一个同步辅助类,它的构造方法接收一个正整数参数作为初始化计数器的值,表示需要等待的线程数量。每个线程完成任务后,都会调用countDown()方法使计数器减1。当计数器减到0时,所有等待线程会被唤醒。
public class CountDownLatch {
public CountDownLatch(int count) { ... }
public void await() throws InterruptedException { ... }
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { ... }
public void countDown() { ... }
public long getCount() { ... }
}
CountDownLatch latch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
// 模拟一些处理时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}).start();
}
latch.await();
System.out.println("所有线程执行完毕!");
在这个示例中,我们创建了一个CountDownLatch对象,并初始化计数器为5。然后创建了5个线程,每个线程都会调用latch.countDown()方法以使计数器减1。最后我们调用latch.await()方法等待所有线程完成。
在Java中,我们可以使用等待方法、join()方法、CountDownLatch类等方式来等待线程完成。使用等待方法可以用于多线程同步,使用join()方法可以等待单个线程完成,使用CountDownLatch类可以等待一组线程完成。要注意等待方法只能在同步代码块中调用,并需要在另一个线程调用notify()或notifyAll()方法来唤醒等待线程。