1. 使用Thread.interrupt()方法
在Java中,一个线程可以通过调用interrupt()方法来向另一个线程发送中断信号。如果该线程正在执行sleep()、wait()或join()方法,它将抛出InterruptedException。
实战示例:
public class InterruptThread {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
System.out.println("线程开始执行...");
Thread.sleep(5000); // 线程休眠5秒
} catch (InterruptedException e) {
System.out.println("线程被中断");
}
});
thread.start();
Thread.sleep(1000); // 主线程休眠1秒
thread.interrupt(); // 向子线程发送中断信号
}
}
2. 使用Object.wait()和Object.notify()方法
在多线程通信中,wait()和notify()方法经常一起使用。当线程调用Object.wait()时,它会释放当前持有的对象锁,并进入等待状态。其他线程可以调用同一对象的notify()或notifyAll()方法来唤醒等待的线程。
实战示例:
public class WaitNotifyExample {
public static void main(String[] args) {
Object lock = new Object();
Thread thread1 = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("线程1等待通知...");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1被唤醒");
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程2获得锁,并唤醒线程1");
lock.notify();
}
});
thread1.start();
thread2.start();
}
}
3. 使用Object.notifyAll()方法
与notify()方法类似,notifyAll()方法也会唤醒同一对象上的所有等待线程。这可以用于唤醒多个线程。
实战示例:
public class NotifyAllExample {
public static void main(String[] args) {
Object lock = new Object();
Thread thread1 = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("线程1等待通知...");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1被唤醒");
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程2获得锁,并唤醒所有等待的线程");
lock.notifyAll();
}
});
thread1.start();
thread2.start();
}
}
4. 使用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(() -> {
System.out.println("线程" + Thread.currentThread().getId() + "正在执行...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有线程已执行完毕");
}
}
5. 使用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().getId() + "正在执行...");
Thread.sleep(1000);
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
通过以上5种方法,你可以有效地在Java中唤醒阻塞的线程。在实际开发中,选择合适的方法取决于具体的需求和场景。
