Java中如何实现主流程遇事件暂停处理后恢复执行?
Java实现主流程暂停处理事件后恢复执行
完全可行,try/catch之所以不行,是因为它是用来处理异常错误场景的,并非设计用来实现正常流程的暂停与恢复,而且catch块执行完毕后只会继续执行try块之后的代码,没法回到暂停的位置继续。下面给你几种实用的实现方式:
1. Object.wait()/notify() 基础同步机制
这是Java最原生的线程协作方式,利用对象锁实现主流程暂停与唤醒。主线程在需要等待事件的位置调用wait()释放锁并进入等待状态,事件触发线程处理完逻辑后调用notify()唤醒主线程,主线程就能从暂停的位置继续执行。
注意:必须在同步块/同步方法中调用wait和notify,否则会抛出IllegalMonitorStateException。
示例代码:
public class EventPauseDemo { // 用来做锁的对象,同时作为事件状态的载体 private final Object eventLock = new Object(); // 标记事件是否触发 private boolean eventTriggered = false; public void mainProcess() throws InterruptedException { for (int i = 0; i < 5; i++) { System.out.println("主流程执行步骤:" + i); // 模拟执行到某个节点,检查是否需要等待事件 if (i == 2) { synchronized (eventLock) { // 事件未触发时,主流程暂停等待 while (!eventTriggered) { System.out.println("主流程暂停,等待事件触发..."); eventLock.wait(); } // 事件处理完成后,主流程从这里继续执行 System.out.println("主流程恢复,继续执行后续逻辑"); } } Thread.sleep(500); } } // 事件触发线程的处理逻辑 public void eventProcess() { synchronized (eventLock) { System.out.println("=== 事件触发,开始处理事件 ==="); // 模拟事件处理耗时 try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("=== 事件处理完成 ==="); // 标记事件已处理,唤醒主线程 eventTriggered = true; eventLock.notify(); } } public static void main(String[] args) { EventPauseDemo demo = new EventPauseDemo(); // 启动主流程线程 new Thread(demo::mainProcess).start(); // 模拟事件延迟触发 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // 启动事件处理线程 new Thread(demo::eventProcess).start(); } }
2. CountDownLatch 一次性事件等待
如果事件是一次性触发的场景,用CountDownLatch会更简洁。主流程创建一个计数为1的CountDownLatch,在需要暂停的位置调用await()阻塞,事件处理线程执行完毕后调用countDown(),计数归0后主流程立即恢复。
示例代码:
import java.util.concurrent.CountDownLatch; public class CountDownLatchDemo { public void mainProcess(CountDownLatch eventLatch) throws InterruptedException { System.out.println("主流程启动"); System.out.println("主流程执行前置逻辑"); // 等待事件触发完成 System.out.println("主流程暂停,等待事件处理..."); eventLatch.await(); // 事件处理完成后继续执行 System.out.println("主流程恢复,执行后续逻辑"); System.out.println("主流程结束"); } public void eventProcess(CountDownLatch eventLatch) { System.out.println("=== 事件触发,开始处理 ==="); try { Thread.sleep(3000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("=== 事件处理完成 ==="); // 通知主流程可以继续 eventLatch.countDown(); } public static void main(String[] args) { CountDownLatch eventLatch = new CountDownLatch(1); CountDownLatchDemo demo = new CountDownLatchDemo(); new Thread(() -> { try { demo.mainProcess(eventLatch); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); // 延迟触发事件 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> demo.eventProcess(eventLatch)).start(); } }
3. CompletableFuture 异步事件处理(Java 8+)
如果事件处理是异步的,用CompletableFuture可以更优雅地实现。主流程通过join()或get()等待Future完成,事件触发时调用complete()方法结束Future,主流程就能继续执行。
示例代码:
import java.util.concurrent.CompletableFuture; public class CompletableFutureDemo { public void mainProcess(CompletableFuture<Void> eventFuture) { System.out.println("主流程启动"); System.out.println("主流程执行前置逻辑"); // 等待事件处理完成 System.out.println("主流程暂停,等待事件处理..."); eventFuture.join(); // 恢复执行后续逻辑 System.out.println("主流程恢复,执行后续逻辑"); System.out.println("主流程结束"); } public void eventProcess(CompletableFuture<Void> eventFuture) { System.out.println("=== 事件触发,开始处理 ==="); try { Thread.sleep(2500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); eventFuture.completeExceptionally(e); } System.out.println("=== 事件处理完成 ==="); // 标记事件处理完成,唤醒主流程 eventFuture.complete(null); } public static void main(String[] args) { CompletableFuture<Void> eventFuture = new CompletableFuture<>(); CompletableFutureDemo demo = new CompletableFutureDemo(); new Thread(() -> demo.mainProcess(eventFuture)).start(); // 延迟触发事件 try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> demo.eventProcess(eventFuture)).start(); } }
这几种方式都能实现你要的效果:主流程在指定节点暂停,等待事件处理完成后恢复执行,完全保留主流程的上下文。
内容的提问来源于stack exchange,提问作者Homewrecker
相关产品推荐
相关产品推荐

