Java线程池详解 - ThreadPoolExecutor
2026/9/3 9:07:31 网站建设 项目流程

Android中经常出现一些任务不执行,重新进入或杀掉进程又可以执行,为什么?
要充分理解拒绝策略,当线程池中的线程已满,究竟是抛出异常try-catch,还是丢弃任务,还是其他的方法处理?

拒绝策略执行的条件:
线程池中的线程数量 > 最大线程数 + 任务队列

如果任务队列的数量设置很大,时间设置很长,也没啥意义。比如:设置100个,1分钟。有些任务可能等待非常久才执行。

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
)

int corePoolSize, // 核心线程数,
定义:线程池中始终保持存活的线程数量,即使这些线程处于空闲状态。除非设置allowCoreThreadTimeOut
executor.allowCoreThreadTimeOut(true); // 允许核心线程超时销毁
int maximumPoolSize, // 最大线程数
定义:线程池允许创建的最大线程数量,包括核心线程和非核心线程。
long keepAliveTime, // 空闲线程存活时间
定义:当线程池中的线程数量超过corePoolSize 时,多余的空闲线程在终止前等待新任务的最长时间。
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 任务队列
定义:用于保存等待执行的任务的阻塞队列。
任务缓冲区,核心作用是在线程资源有限时暂存待执行任务,平衡任务提交速度与线程处理能力。
SynchronousQueue(同步移交队列)
LinkedBlockingQueue(无界/有界队列)
ArrayBlockingQueue(有界队列)
PriorityBlockingQueue(优先级队列)
DelayQueue(延迟队列)
ThreadFactory threadFactory, // 线程工厂
用于创建新线程的工厂类。
RejectedExecutionHandler handler // 拒绝策略
定义:当线程池和队列都满了,无法处理新任务时的处理策略。
内置拒绝策略
AbortPolicy(默认):抛出RejectedExecutionException
CallerRunsPolicy:调用者线程执行 - 可能会在主线程中执行耗时任务,可能会奔溃
DiscardPolicy:静默丢弃
DiscardOldestPolicy:丢弃队列中最旧的任务


线程数变化示意图:
任务提交 → 当前线程数 < corePoolSize → 创建新线程
任务提交 → 当前线程数 >= corePoolSize → 任务入队
任务提交 → 队列已满 && 当前线程数 < maximumPoolSize → 创建新线程
任务提交 → 队列已满 && 当前线程数 >= maximumPoolSize → 执行拒绝策略

这个例子创建多个线程池,如果第1个满了,使用第2个,如果又满了,就使用新的线程执行。

/** * Author : wn * Email : maoning20080809@163.com * Date : 2025/12/21 12:28 * Description : 测试线程池 */ public classThreadPoolMainActivityextends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.thread_pool_main); findViewById(R.id.thread_pool_btn1).setOnClickListener(this); findViewById(R.id.thread_pool_btn2).setOnClickListener(this); findViewById(R.id.thread_pool_btn3).setOnClickListener(this); findViewById(R.id.thread_pool_btn4).setOnClickListener(this); } @Override public void onClick(View v) { if(v.getId() == R.id.thread_pool_btn1){ ThreadPoolExecutorHelper.test1(); } else if(v.getId() == R.id.thread_pool_btn2){ ThreadPoolExecutorHelper.test2(); } else if(v.getId() == R.id.thread_pool_btn3){ThreadPoolExecutorAutoHelper.test3();} else if(v.getId() == R.id.thread_pool_btn4){ThreadPoolExecutorAutoHelper.test4();} } }
/** * Author : wn * Email : maoning20080809@163.com * Date : 2025/12/21 17:10 * Description : */ public classThreadPoolExecutorAutoHelper{ //线程池自动切换, 线程最大数(核心+非核心线程)+等待队列都用完,才异常。 public static void test3(){ ThreadPoolExecutor cpuExecutor = ThreadPoolExecutorAuto.getCpuExecutor(); //ThreadPoolMonitor threadPoolMonitor = new ThreadPoolMonitor(cpuExecutor); for(int i = 0; i < 50; i++){ ThreadTask3 threadTask3 = new ThreadTask3("ThreadTask3 i = " + i); try { cpuExecutor.execute(threadTask3); LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, "ThreadPoolExecutorHelper test3() i = " + i); } catch (RejectedExecutionException e){ try { //cpu线程池异常 , 使用io线程池 , 线程最大数+等待队列 LogUtils.Companion.w(ThreadPoolExecutorHelper.TAG, "ThreadPoolExecutorAutoHelper test3() cpu RejectedExecutionException e = " + e.getMessage()); ThreadPoolExecutor ioExecutor = ThreadPoolExecutorAuto.getIoExecutor(); ioExecutor.execute(threadTask3); } catch (RejectedExecutionException e1){ //io线程池也异常, LogUtils.Companion.e(ThreadPoolExecutorHelper.TAG, "ThreadPoolExecutorAutoHelper test3() io RejectedExecutionException e = " + e.getMessage()); //使用新的Thread执行,或者想想其他的扩展实现, 一定要使用start() new Thread(threadTask3, "cpu-io all exception").start(); } } } } //先调用test3测试线程池满了以后,使用子线程。再用比较少的线程看看线程池能否正常执行 public static void test4(){ ThreadPoolExecutor cpuExecutor = ThreadPoolExecutorAuto.getCpuExecutor(); //ThreadPoolMonitor threadPoolMonitor = new ThreadPoolMonitor(cpuExecutor); for(int i = 0; i < 3; i++){ ThreadTask3 threadTask3 = new ThreadTask3("ThreadTask3 i = " + i); try { cpuExecutor.execute(threadTask3); LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, "ThreadPoolExecutorHelper test4() i = " + i); } catch (RejectedExecutionException e){ try { //cpu线程池异常 , 使用io线程池 , 线程最大数+等待队列 LogUtils.Companion.w(ThreadPoolExecutorHelper.TAG, "ThreadPoolExecutorAutoHelper test4() cpu RejectedExecutionException e = " + e.getMessage()); ThreadPoolExecutor ioExecutor = ThreadPoolExecutorAuto.getIoExecutor(); ioExecutor.execute(threadTask3); } catch (RejectedExecutionException e1){ //io线程池也异常, LogUtils.Companion.e(ThreadPoolExecutorHelper.TAG, "ThreadPoolExecutorAutoHelper test4() io RejectedExecutionException e = " + e.getMessage()); //使用新的Thread执行,或者想想其他的扩展实现, 一定要使用start() new Thread(threadTask3, "cpu-io all exception").start(); } } } } }
/** * Author : wn * Email : maoning20080809@163.com * Date : 2025/12/21 15:17 * Description : 多线程池自动切换,如果cpu线程池满了,自动切换到io线程池 */ public classThreadPoolExecutorAuto{//CPU密集型线程池 private static ThreadPoolExecutor cpuExecutor; //IO密集型任务池 private static ThreadPoolExecutor ioExecutor;//单线程顺序执行池 private static ThreadPoolExecutor serialExecutor; static { //线程数 int cpuCount = Runtime.getRuntime().availableProcessors(); //int cpuCount = 2; LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, "ThreadPoolExecutorManager cpuCount = " + cpuCount); //CPU密集型:处理图像计算等 cpuExecutor = new ThreadPoolExecutor( cpuCount, cpuCount + 1, 3L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), //队列也不能太多,会导致等待时间太久。 new CustomThreadFactory("ThreadPoolExecutorAuto my-cpu-pool", Thread.MAX_PRIORITY - 1), new ThreadPoolExecutor.AbortPolicy() //抛出异常策略 ); //IO密集型:网络请求、文件读写 ioExecutor = new ThreadPoolExecutor( cpuCount * 2, cpuCount * 3, 6L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20), new CustomThreadFactory("ThreadPoolExecutorAuto my-io-pool", Thread.NORM_PRIORITY), new ThreadPoolExecutor.AbortPolicy() //抛出异常测试了 ); //串行执行:数据库操作等需要顺序执行的任务 serialExecutor = new ThreadPoolExecutor( 1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new CustomThreadFactory("ThreadPoolExecutorAuto my-serial-pool", Thread.NORM_PRIORITY) ); //防止内存泄漏:监听应用生命周期 Application application = MyApp.myApp; application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { } @Override public void onActivityStarted(@NonNull Activity activity) { } @Override public void onActivityResumed(@NonNull Activity activity) { } @Override public void onActivityPaused(@NonNull Activity activity) { } @Override public void onActivityStopped(@NonNull Activity activity) { } @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { } @Override public void onActivityDestroyed(@NonNull Activity activity) { //清理与Activity相关的任务 LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, "清理与Activity相关的任务 ThreadPoolExecutorManager onActivityDestroyed " + activity); } }); } //CPU密集型线程池 public static ThreadPoolExecutor getCpuExecutor(){ return cpuExecutor; } //IO密集型任务池 public static ThreadPoolExecutor getIoExecutor(){ return ioExecutor; } //单线程顺序执行池 public static ThreadPoolExecutor getSerialExecutor(){ return serialExecutor; } }
/** * Author : wn * Email : maoning20080809@163.com * Date : 2025/12/21 15:50 * Description : */ public classThreadTask3implements Runnable{ //private static final String TAG = "ThreadTask2"; private String threadTaskName; public ThreadTask3(String name){ this.threadTaskName = name; } private static int taskCount = 1; @Override public void run() { try { Thread.sleep(100); LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, "ThreadTask3 执行任务:taskCount = " +taskCount + " isMain = " + isMainThread() +" , " + threadTaskName +" , `" + Thread.currentThread().getName() +" , " + Thread.currentThread().getId() +" , " + this.getClass()); taskCount ++; //这里执行的是子线程, 如果使用handler刷新,必须指定在主线程中执行:Looper.getMainLooper() /*new Handler(Looper.getMainLooper()).post(() -> { //LogUtils.Companion.i(TAG, "ThreadTask2 执行任务:" + Thread.currentThread().getName() +" , " + Thread.currentThread().getId()); });*/ } catch (Exception e){ e.printStackTrace(); } } public boolean isMainThread() { // 方法1:比较当前线程和主线程的线程对象 return Looper.myLooper() == Looper.getMainLooper(); //return Looper.getMainLooper().getThread() == Thread.currentThread(); } }
/** * Author : wn * Email : maoning20080809@163.com * Date : 2025/12/21 15:37 * Description : 线程池监控 */ public classThreadPoolMonitor{ private ThreadPoolExecutor executor; private ScheduledExecutorService monitor; public ThreadPoolMonitor(ThreadPoolExecutor executor){ this.executor = executor; //启动监控 monitor = Executors.newSingleThreadScheduledExecutor(); monitor.scheduleAtFixedRate(this::reportStatus, 0, 5, TimeUnit.SECONDS); } private void reportStatus(){ LogUtils.Companion.d(ThreadPoolExecutorHelper.TAG, "ThreadPoolMonitor reportStatus()");StringBuilder sb = new StringBuilder(); sb.append("ThreadPoolMonitor reportStatus() "); sb.append(" , Pool Size : " + executor.getPoolSize()); sb.append(" , Max Pool Size : " + executor.getMaximumPoolSize()); sb.append(" , Core Pool Size : " + executor.getCorePoolSize()); sb.append(" , Active Threads : " + executor.getActiveCount()); sb.append(" , Queue Size : " + executor.getQueue().size()); sb.append(" , Completed Tasks : " + executor.getCompletedTaskCount()); sb.append(" , Largest Pool Size : " + executor.getLargestPoolSize()); LogUtils.Companion.i(ThreadPoolExecutorHelper.TAG, sb.toString());//动态调整:如果队列长期满载,增加核心线程数 - 可以灵活配置 if(executor.getQueue().size() > 80){ executor.setCorePoolSize(Math.min(executor.getCorePoolSize() + 2, executor.getMaximumPoolSize())); } } public void shutdown(){ executor.shutdown(); monitor.shutdown(); } }

thread_pool_main.xml布局

<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" > <androidx.appcompat.widget.AppCompatTextView android:id="@+id/thread_pool_title" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="20dp" android:textSize="30sp" android:textColor="@color/black" android:text="测试线程池"/> <androidx.appcompat.widget.AppCompatButton android:id="@+id/thread_pool_btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/thread_pool_title" android:text="测试线程池满抛出异常"/> <androidx.appcompat.widget.AppCompatButton android:id="@+id/thread_pool_btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/thread_pool_btn1" android:textColor="@color/red" android:text="测试线程池状态"/> <androidx.appcompat.widget.AppCompatButton android:id="@+id/thread_pool_btn3" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/thread_pool_btn2" android:textColor="@color/blue" android:text="测试线程池自动切换设计 - 非常多线程同时执行"/> <androidx.appcompat.widget.AppCompatButton android:id="@+id/thread_pool_btn4" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/thread_pool_btn3" android:textColor="@color/blue" android:text="测试线程池自动切换设计 - 少量线程执行"/> </androidx.constraintlayout.widget.ConstraintLayout>

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询