Android 学习线程池ThreadPoolExecutor
ThreadPoolExecutor构造方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | @Test public void ThreadPoolTest() { ExecutorService executor = new ThreadPoolExecutor( //corePoolSize:核心线程数 3 , //maximumPoolSize:最大线程数 5 , //空闲线程最大闲置时间 keepAliveTime:时间的值, unit:时间的单位 例如秒 10L, TimeUnit.SECONDS, //用于保存任务的队列,可以为无界、有界、同步移交三种队列类型之一, // 当池子里的工作线程数大于corePoolSize时,这时新进来的任务会被放到队列中 //一共有3种: //SynchronousQueue(同步移交队列):队列不作为任务的缓冲方式,可以简单理解为队列长度为零 //LinkedBlockingQueue(无界队列):队列长度不受限制,当请求越来越多时(任务处理速度跟不上任务提交速度造成请求堆积) // 可能导致内存占用过多或OOM //ArrayBlockintQueue(有界队列):队列长度受限,当队列满了就需要创建多余的线程来执行任务 new ArrayBlockingQueue<>( 3 ), //创建线程的工厂类,默认使用Executors.defaultThreadFactory(),也可以使用guava库的ThreadFactoryBuilder来创建 Executors.defaultThreadFactory(), //拒绝策略: //线程池无法继续接收任务(队列已满且线程数达到maximunPoolSize)时的饱和策略, // 取值有 // AbortPolicy、中断抛出异常 // CallerRunsPolicy、默默丢弃任务,不进行任何通知 // DiscardOldestPolicy、丢弃掉在队列中存在时间最久的任务 // DiscardPolicy 让提交任务的线程去执行任务(对比前三种比较友好一丢丢) new ThreadPoolExecutor.AbortPolicy() ); System.out.println( "开始执行线程里面的线程" ); for ( int i = 0 ; i < 6 ; i++) { executor.execute(() -> { System.out.println(Thread.currentThread().getName() + ":正在执行任务" ); }); } executor.shutdown(); System.out.println( "线程执行结束" ); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0 ) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null ) throw new NullPointerException(); this .corePoolSize = corePoolSize; this .maximumPoolSize = maximumPoolSize; this .workQueue = workQueue; this .keepAliveTime = unit.toNanos(keepAliveTime); this .threadFactory = threadFactory; this .handler = handler; } |
Okhttp源码中关于线程池的使用 在Dispatcher里面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public synchronized ExecutorService executorService() { if (executorService == null ) { //corePoolSize=0,maxPoolSize为很大的数,同步移交队列,也就是说不维护常驻线程(核心线程), // 每次来请求直接创建新线程来处理任务,也不使用队列缓冲,会自动回收多余线程, // 由于将maxPoolSize设置成Integer.MAX_VALUE, // 当请求很多时就可能创建过多的线程,导致资源耗尽OOM //这里可以调用Executors的方法达到同样的效果 // public static ExecutorService newCachedThreadPool() { // return new ThreadPoolExecutor(0, Integer.MAX_VALUE, // 60L, TimeUnit.SECONDS, // new SynchronousQueue<Runnable>()); // } executorService = new ThreadPoolExecutor( 0 , Integer.MAX_VALUE, 60 , TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), Util.threadFactory( "OkHttp Dispatcher" , false )); } return executorService; } |
Worker
ThreadPoolExecutor的execute()跳入进去发现会有一个新的类Worker。Worker维护了一个thread和一个Runnable,运行时调用ThreadPoolExecutor的runWorker()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | private final class Worker extends AbstractQueuedSynchronizer implements Runnable { final Thread thread; Runnable firstTask; //构造方法 Worker(Runnable firstTask) { setState(- 1 ); // inhibit interrupts until runWorker 在运行Worker之前禁止中断 this .firstTask = firstTask; //获取创建线程的工厂产生一个线程 this .thread = getThreadFactory().newThread( this ); } //将run方法交给ThreadPoolExecutor的runWorker调用 public void run() { runWorker( this ); } } final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; //将Worker里面要执行的Runnable交给task w.firstTask = null ; w.unlock(); // allow interrupts 先解锁Worker try { while (task != null || (task = getTask()) != null ) { w.lock(); //给Worker加锁 // If pool is stopping, ensure thread is interrupted; // if not, ensure thread is not interrupted. This // requires a recheck in second case to deal with // shutdownNow race while clearing interrupt //翻译: // 如果池正在停止,确保线程被中断; //如果没有,确保线程没有中断。这 //在第二种情况下需要重新检查才能处理 //在清除中断的同时停止运转 if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && !wt.isInterrupted()) wt.interrupt(); try { beforeExecute(wt, task); //开始执行 Throwable thrown = null ; try { task.run(); } catch (Throwable x) { //... } finally { afterExecute(task, thrown); //执行结束之后调用 } } finally { task = null ; w.completedTasks++; w.unlock(); //解锁 } } } } |
ThreadPoolExecutor的executor()方法添加Worker
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public void execute(Runnable command) { if (command == null ) throw new NullPointerException(); /* * 有3种情况 * 1.运行线程数少于核心线程数,那么Worker就是一个firstTask * * 2.如果运行线程大于核心线程。就会判断是否有已经运行结束的线程, * 如果有就拿来使用,如果没有就创建新线程 * * 3. 如果排队的任务也就是BlockingQueue队列满了就会执行拒绝策略 */ int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true )) return ; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0 ) addWorker( null , false ); } else if (!addWorker(command, false )) reject(command); } |
分类:
Android 源码学习
标签:
Android
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)