当面试官问Java线程池时,你应该了解些什么?
发布时间:2021-12-07 15:24:14 所属栏目:教程 来源:互联网
导读:根据江门站长网 Www.0750Zz.Com报道 Java面试中,线程池也算是一个高频的问题,其实就JDK源码来看线程池这一块的实现代码应该算是写的清晰易懂的,通过这篇文章,我们就来盘点一下线程池的知识点。 本文基于JDK1.8源码进行分析 首先看下线程池构造函数: pub
Throwable thrown = null; try { //真正的任务执行逻辑 task.run(); } catch (RuntimeException x) { thrown = x; throw x; } catch (Error x) { thrown = x; throw x; } catch (Throwable x) { thrown = x; throw new Error(x); } finally { //该方法是个空的实现,如果有需要用户可以自己继承该类进行实现 afterExecute(task, thrown); } } finally { //这里设为null,也就是循环体再执行的时候会调用getTask方法 task = null; w.completedTasks++; w.unlock(); } } completedAbruptly = false; } finally { //当指定任务执行完成,阻塞队列中也取不到可执行任务时,会进入这里,做一些善后工作,比如在corePoolSize跟maximumPoolSize之间的woker会进行回收 processWorkerExit(w, completedAbruptly); } } woker线程的执行流程就是首先执行初始化时分配给的任务,执行完成以后会尝试从阻塞队列中获取可执行的任务,如果指定时间内仍然没有任务可以执行,则进入销毁逻辑。 注:这里只会回收corePoolSize与maximumPoolSize直接的那部分woker 理解了整个线程池的运行原理以后,再来看下JDK默认提供的线程池类型就会一目了然了: public static ExecutorService newFixedThreadPool(int nThreads) { //corePoolSize跟maximumPoolSize值一样,同时传入一个无界阻塞队列 //根据上面分析的woker回收逻��,该线程池的线程会维持在指定线程数,不会进行回收 return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ExecutorService newSingleThreadExecutor() { //线程池中只有一个线程进行任务执行,其他的都放入阻塞队列 //外面包装的FinalizableDelegatedExecutorService类实现了finalize方法,在JVM垃圾回收的时候会关闭线程池 return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); } public static ExecutorService newCachedThreadPool() { //这个线程池corePoolSize为0,maximumPoolSize为Integer.MAX_VALUE,意思也就是说来一个任务就创建一个woker,回收时间是60s return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } 最后再说说初始化线程池时线程数的选择: 如果任务是IO密集型,一般线程数需要设置2倍CPU数以上,以此来尽量利用CPU资源。 如果任务是CPU密集型,一般线程数量只需要设置CPU数加1即可,更多的线程数也只能增加上下文切换,不能增加CPU利用率。 上述只是一个基本思想,如果真的需要精确的控制,还是需要上线以后观察线程池中线程数量跟队列的情况来定。 ![]() (编辑:宿州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐