在Java编程中,等待是一个常见的操作,尤其是在多线程环境中。正确地实现等待机制可以有效地提高代码的执行效率和同步性。以下是五种实用的Java程序等待方法,帮助你轻松实现代码同步与阻塞。
1. 使用sleep()方法
sleep()方法是Thread类提供的一个静态方法,可以让当前线程暂停执行指定的毫秒数。这是一种简单直接的等待方式,但需要注意以下几点:
sleep()方法不会释放线程占有的任何监视器锁,因此,如果在同步块中使用sleep(),可能会导致死锁。- 使用
sleep()时,如果发生中断,则sleep()方法会抛出InterruptedException。
public class SleepExample {
public static void main(String[] args) {
try {
System.out.println("线程开始休眠...");
Thread.sleep(2000); // 休眠2秒
System.out.println("线程结束休眠...");
} catch (InterruptedException e) {
System.out.println("线程被中断");
}
}
}
2. 使用wait()方法
wait()方法是Object类提供的一个方法,可以让当前线程等待,直到其他线程调用该对象的notify()或notifyAll()方法。在使用wait()时,需要注意以下几点:
wait()方法必须在使用它的对象监视器上调用。- 使用
wait()时,如果发生中断,则会抛出InterruptedException。 - 使用
wait()后,必须使用notify()或notifyAll()方法唤醒等待的线程。
public class WaitExample {
public synchronized void waitMethod() {
try {
System.out.println("线程进入等待状态...");
wait();
System.out.println("线程被唤醒...");
} catch (InterruptedException e) {
System.out.println("线程被中断");
}
}
public synchronized void notifyMethod() {
System.out.println("线程调用notify...");
notify();
}
public static void main(String[] args) {
WaitExample example = new WaitExample();
Thread thread = new Thread(example::waitMethod);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
example.notifyMethod();
}
}
3. 使用CountDownLatch
CountDownLatch是一个同步辅助类,用于控制多个线程等待某个事件的发生。它允许一个或多个线程等待一组事件的发生。
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
System.out.println("线程" + Thread.currentThread().getName() + "开始执行...");
latch.await(); // 等待计数器减为0
System.out.println("线程" + Thread.currentThread().getName() + "执行完毕。");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程开始执行...");
latch.countDown(); // 减少计数器
latch.countDown();
latch.countDown();
}
}
4. 使用CyclicBarrier
CyclicBarrier是一个同步辅助类,它允许一组线程相互等待,直到所有线程都到达某个点。当所有线程都到达这个点时,CyclicBarrier会执行一个动作,然后所有线程继续执行。
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有线程都到达了屏障...");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
System.out.println("线程" + Thread.currentThread().getName() + "开始执行...");
barrier.await(); // 等待所有线程到达屏障
System.out.println("线程" + Thread.currentThread().getName() + "执行完毕。");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
5. 使用Future
Future是java.util.concurrent包中的一个接口,它代表了一个异步计算的结果。通过Future,你可以查询异步任务的状态,并获取最终的结果。
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {
try {
Thread.sleep(2000);
return "异步计算结果";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
}
});
try {
String result = future.get(); // 等待异步任务完成
System.out.println("异步任务结果:" + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
通过以上五种方法,你可以根据实际需求选择合适的等待机制,实现Java程序中的代码同步与阻塞。在实际开发中,合理运用这些方法,可以大大提高代码的执行效率和稳定性。
