java线程池

  1、以下是ThreadPoolExecutor参数完备构造方法:

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

    corePoolSize:线程池的大小,当刚开始创建线程池时,线程数为0,当线程池中线程数量多于corePoolSize时会存于缓存队列

    maxinumPoolSize:线程池容纳的最多线程数量

    keepAliveTime:空闲线程的存活时间,一般情况下是当前线程线程数超过线程池大小,才会进行回收

    unit:keepAliveTime的事件单位

    workQueue:缓存队列

      ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小;

      LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;

      synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。

    threadFactory:通过这个参数你可以自定义如何创建线程,例如你可以给线程指定一个有意义的名字。

    handler:通过这个参数你可以自定义任务的拒绝策略。如果线程池中所有的线程都在忙碌,并且工作队列也满了(前提是工作队列是有界队列),那么此时提交任务,线程池就会拒绝接收。至于拒绝的策略,你可以通过 handler 这个参数来指定。

      ThreadPoolExecutor 已经提供了以下 4 种策略。

      

  CallerRunsPolicy:提交任务的线程自己去执行该任务。

        AbortPolicy:默认的拒绝策略,会 throws RejectedExecutionException。

        DiscardPolicy:直接丢弃任务,没有任何异常抛出。

        DiscardOldestPolicy:丢弃最老的任务,其实就是把最早进入工作队列的任务丢弃,然后把新任务加入到工作队列。

  执行流程:

      线程池创建线程,会判断当前线程数是否大于corePoolSize。

      如果大于则存在缓存队列,缓冲队列存满后会继续创建线程直到maximumPoolSize,抛出拒绝的异常。

      如果小于则创建线程,执行任务,执行完后会从缓存队列中取任务再执行

  2、封装线程池

  

  1. public static ExecutorService newFixedThreadPool(int nThreads) {
  2.  
  3.    return new ThreadPoolExecutor(nThreads, nThreads,
  4.  
  5. 0L, TimeUnit.MILLISECONDS,
  6.  
  7. new LinkedBlockingQueue<Runnable>());
  8.  
  9.   }
  10.  
  11.   //创建的线程池corePoolSize和maximumPoolSize值是相等的,它使用的LinkedBlockingQueue;

  

  1. public static ExecutorService newSingleThreadExecutor() {
  2.  
  3.    return new FinalizableDelegatedExecutorService
  4.  
  5. (new ThreadPoolExecutor(1, 1,
  6.  
  7. 0L, TimeUnit.MILLISECONDS,
  8.  
  9. new LinkedBlockingQueue<Runnable>()));
  10.  
  11. }
  12.  
  13. //将corePoolSize和maximumPoolSize都设置为1,也使用的LinkedBlockingQueue
  1. public static ExecutorService newCachedThreadPool() {
  2.  
  3. return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
  4.  
  5. 60L, TimeUnit.SECONDS,
  6.  
  7. new SynchronousQueue<Runnable>());
  8.  
  9. }
  10.  
  11. //将corePoolSize设置为0,将maximumPoolSize设置为Integer.MAX_VALUE,使用的SynchronousQueue,也就是说来了任务就创建线程运行,当线程空闲超过60秒,就销毁线程

  日常工作中不建议使用以上线程池:

    1)newFixedThreadPool 和 newSingleThreadExecutor:主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。

    2)newCachedThreadPool 和 newScheduledThreadPool:主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

  创建多少线程合适呢?

    创建多少线程合适,要看多线程具体的应用场景。我们的程序一般都是 CPU 计算和 I/O 操作交叉执行的,由于 I/O 设备的速度相对于 CPU 来说都很慢,所以大部分情况下,I/O 操作执行的时间相对于 CPU 计算来说都非常长,这种场景我们一般都称为 I/O 密集型计算;和 I/O 密集型计算相对的就是 CPU 密集型计算了,CPU 密集型计算大部分场景下都是纯 CPU 计算。I/O 密集型程序和 CPU 密集型程序,计算最佳线程数的方法是不同的。

    对于CPU密集型来说,多线程主要目的是提成CPU利用率,保持和CPU核数一致即可。不过在工程上,,线程的数量一般会设置为“CPU 核数 +1”,这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以顶上,从而保证 CPU 的利用率。

    对于IO密集型来说,一般是最佳线程数 =CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]

    总之上述仅可代表项目初始时设定的线程数量,后续随着实际应用场景进行调整优化

java线程池及创建多少线程合适的更多相关文章

  1. Java线程池的创建详解

    本篇文章主要总结了Java创建线程池的三种方式以及线程池参数的详细说明,对线程池感兴趣的同学可以作为参考学习. 1)通过工具类java.util.concurrent.Executors的静态方法来创 ...

  2. JAVA线程池的创建与使用

    为什么要用线程池? 我们都知道,每一次创建一个线程,JVM后面的工作包括:为线程建立虚拟机栈.本地方法栈.程序计数器的内存空间(下图可看出),所以线程过多容易导致内存空间溢出.同时,当频繁的创建和销毁 ...

  3. JAVA线程池的创建

    /** * 创建不同类型的线程池 Executors * * @author */ public class ThreadPoolTest01 { public static void main(St ...

  4. Java面试必问之线程池的创建使用、线程池的核心参数、线程池的底层工作原理

    一.前言 大家在面试过程中,必不可少的问题是线程池,小编也是在面试中被问啥傻了,JUC就了解的不多.加上做系统时,很少遇到,自己也是一知半解,最近看了尚硅谷阳哥的课,恍然大悟,特写此文章记录一下!如果 ...

  5. java多线程系类:JUC线程池:05之线程池原理(四)(转)

    概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...

  6. java多线程系类:JUC线程池:03之线程池原理(二)(转)

    概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...

  7. java多线程系类:JUC线程池:02之线程池原理(一)

    在上一章"Java多线程系列--"JUC线程池"01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我 ...

  8. java多线程、线程池及Spring配置线程池详解

    1.java中为什么要使用多线程使用多线程,可以把一些大任务分解成多个小任务来执行,多个小任务之间互不影像,同时进行,这样,充分利用了cpu资源.2.java中简单的实现多线程的方式 继承Thread ...

  9. 线程池(ThreadPool)创建

    线程池创建方式jdk1.5 Java通过Executors(jdk1.5并发包)提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活 ...

随机推荐

  1. 从零开始のcocos2dx生活(十一)TableView

    目录 简述 主要变量 主要方法 setVerticalFillOrder reloadData cellAtIndex updateCellAtIndex insertCellAtIndex remo ...

  2. 第一次看CCControl

    Control中有九种可能的事件,定义在.h文件中,另外还定义四种状态,用来表示控件高亮等. 在初始化控件的时候: bool Control::init() { if (Layer::init()) ...

  3. StatePattern(状态模式)-----Java/.Net

    在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式. 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context ...

  4. SpringBoot 2.X整合Mybatis

    1.创建工程环境 勾选Web.Mybatis.MySQL,如下 依赖如下 <dependency> <groupId>org.springframework.boot</ ...

  5. 2020面试还搞不懂MyBatis?快看看这27道面试题!(含答案和思维导图)

    前言 MyBatis是一个优秀的持久层ORM框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL 本身,而不需要花费精力去处理例如注册驱动.创建connection.创建statem ...

  6. C++中重载、重写(覆盖)和隐藏的区别

    转载自:https://blog.csdn.net/zx3517288/article/details/48976097 基本概念: 重载:是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个 ...

  7. spring boot集成jsp

    我们在使用spring boot进行web项目开发的时候,可能会选择页面用jsp.spring boot默认使用的html的,现在我们来看下如何集成jsp页面进行开发. 1.pom.xml文件引入所需 ...

  8. 【转】基于ArcGIS for javascript api 轨迹回放

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  9. 【Spring Boot 源码解读】之 【为何引入了 Jedis 依赖最后用的还是 Lettuce 客户端?】

    1.Spring Boot 2.x 的两种 Redis 客户端 首先,我们都知道,从 Spring Boot 2.x 开始 Lettuce 已取代 Jedis 成为首选 Redis 的客户端.当然 S ...

  10. 微信小程序修改checkbox的样式

    修改前: 修改后: wxml代码: <checkbox class="checkbox" /> wxss代码: /* checkbox选中钱样式 */ checkbox ...