Java如何让回调函数在主线程中执行?
如何让回调函数在主线程执行
下面是几种针对你的测试代码的修改方案,都能实现回调在主线程运行的需求:
方案1:主线程维护任务队列,轮询处理回调
核心思路是让异步任务只负责把回调任务提交到线程安全的队列,主线程在等待期间主动从队列取出任务并执行,这样回调就会在主线程上下文运行。
修改后的完整代码:
import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import org.junit.Test; @Test void threadTest() throws InterruptedException { System.out.println("main thread:" + Thread.currentThread()); BlockingQueue<Runnable> callbackQueue = new LinkedBlockingQueue<>(); new Thread(new AsyncTask(() -> callbackQueue.put(this::callback))).start(); // 主线程等待异步任务完成后,处理队列中的回调 Thread.sleep(1100); Runnable callbackTask; while ((callbackTask = callbackQueue.poll()) != null) { callbackTask.run(); } } private void callback() { System.out.println("callback executed in: " + Thread.currentThread()); } static class AsyncTask implements Runnable { private final Runnable runnable; public AsyncTask(Runnable runnable) { this.runnable = runnable; } @Override public void run() { System.out.println("other thread: " + Thread.currentThread()); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } this.runnable.run(); } }
方案2:用CountDownLatch同步,主线程触发回调
通过CountDownLatch让异步任务完成后发出信号,主线程收到信号后直接执行回调,这种方式逻辑简单,适合单个回调的场景。
修改后的代码:
import java.util.concurrent.CountDownLatch; import org.junit.Test; @Test void threadTest() throws InterruptedException { System.out.println("main thread:" + Thread.currentThread()); CountDownLatch latch = new CountDownLatch(1); new Thread(new AsyncTask(latch)).start(); // 主线程阻塞等待异步任务完成 latch.await(); // 回调在主线程执行 callback(); } private void callback() { System.out.println("callback executed in: " + Thread.currentThread()); } static class AsyncTask implements Runnable { private final CountDownLatch latch; public AsyncTask(CountDownLatch latch) { this.latch = latch; } @Override public void run() { System.out.println("other thread: " + Thread.currentThread()); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } // 异步任务完成,释放latch latch.countDown(); } }
方案3:利用CompletableFuture(Java 8+)
借助Java 8引入的CompletableFuture异步工具类,让主线程等待异步任务完成后执行回调,代码更简洁现代。
修改后的代码:
import java.util.concurrent.CompletableFuture; import org.junit.Test; @Test void threadTest() throws InterruptedException { System.out.println("main thread:" + Thread.currentThread()); CompletableFuture<Void> asyncTask = CompletableFuture.runAsync(() -> { System.out.println("other thread: " + Thread.currentThread()); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } }); // 等待异步任务结束,主线程执行回调 asyncTask.join(); callback(); } private void callback() { System.out.println("callback executed in: " + Thread.currentThread()); }
各方案适用场景
- 方案1:适合需要处理多个异步回调任务的场景,主线程可以持续轮询队列处理任务;
- 方案2:适合单个回调的简单场景,代码逻辑直观易懂;
- 方案3:适合Java 8及以上版本的项目,利用原生异步API简化代码。
内容的提问来源于stack exchange,提问作者PeMa
相关产品推荐
相关产品推荐

