ThreadUtil 异步执行,线程安全、非阻塞的工具类

发布于:2025-05-11 ⋅ 阅读:(23) ⋅ 点赞:(0)


import android.os.Handler;
import android.os.Looper;

import java.util.concurrent.Callable;
import java.util.concurrent.Consumer;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ThreadUtils {
    private static final String TAG = "ThreadUtils";
    private static ThreadUtils instance;

    private final ExecutorService fixedThreadPool;
    private final Executor mainThread;

    private ThreadUtils() {
        fixedThreadPool = Executors.newFixedThreadPool(8);
        mainThread = new MainThreadExecutor();
    }

    public static synchronized ThreadUtils getInstance() {
        if (instance == null) {
            instance = new ThreadUtils();
        }
        return instance;
    }

    private static class MainThreadExecutor implements Executor {
        private final Handler mainThreadHandler = new Handler(Looper.getMainLooper());

        @Override
        public void execute(Runnable command) {
            mainThreadHandler.post(command);
        }
    }

    public void execute(Runnable runnable) {
        fixedThreadPool.execute(runnable);  // 不建议再阻塞式执行
    }

    public void executeMain(Runnable runnable) {
        mainThread.execute(runnable);
    }

    public static boolean isMainThread() {
        return Looper.getMainLooper() == Looper.myLooper();
    }

    /**
     * 异步执行任务 + 超时控制 + 回调
     */
    public <T> void executeWithTimeoutAsync(
            Callable<T> task,
            long timeout,
            TimeUnit unit,
            Consumer<T> onSuccess,
            Consumer<Throwable> onError
    ) {
        Future<T> future = fixedThreadPool.submit(task);

        new Thread(() -> {
            try {
                T result = future.get(timeout, unit);
                mainThread.execute(() -> onSuccess.accept(result));
            } catch (TimeoutException e) {
                future.cancel(true);
                mainThread.execute(() -> onError.accept(e));
            } catch (ExecutionException | InterruptedException e) {
                mainThread.execute(() -> onError.accept(e));
            }
        }).start();
    }
}

依赖


public interface Consumer<T> {
    void accept(T t);
}

使用方法:

现在的 ThreadUtils 是线程安全、非阻塞、支持超时和主线程回调的完整工具类,推荐这样使用:

ThreadUtils.getInstance().executeWithTimeoutAsync(
    () -> doParse(scanResult),
    2, TimeUnit.SECONDS,
    result -> updateUI(result),
    error -> Log.e("BB", "处理失败或超时:" + error.getMessage())
);