栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

Java线程池

Java 更新时间:发布时间: 百科书网 趣学号

Java线程池
一、Executors创建线程池
    newFixedThreadPool:固定指定线程数的线程池
    newSingleThreadExector:只有一个线程的线程池
    newCachedThreadPool:不限线程数上限的线程池,任何提交的任务都将立即执行
    newScheduledThreadPool:定时周期性执行的线程池

    任务类型:
    线程执行的任务,分为两种:1.实现Runnable接口;2.实现Callable接口;
        区别:
        Runnable:void Runnable.run();
        Callable:T Callable.call() throws Exception
        说明:Runnable没有返回值且不能抛出异常,Callable可以有返回值允许抛出异常。

    线程池提交任务的3种方式:
        返回结果:Future submit(Callable task);
        返回空:Future submit(Runnable task),该方法有返回值,恒为空null
        不返回结果:void execute(Runnable command);

二、优化创建线程池
    避免直接使用Executors.newXXXThreadPool()的快捷方法创建线程池,因为Executors默认使用无界队列,容易导致OOM(内存不足)。所以需要明确指定使用有界队列(指定队列最大长度),且应当指明拒绝任务时发生的行为(策略)

    new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler);
    corePoolSize(核心线程数):线程池中常驻的线程数,线程池初始化时默认是没有线程的,当任务来临时才开始创建线程去执行任务。
    maximumPoolSize(最大线程数):在核心线程数的基础上,当workQueue队列填满时会创建多于corePoolSize且总线程数不超过maxPoolSize的线程
    keepAliveTime(非核线程空闲时长):当非核心线程的空闲时间该值时,会被自动终止回收掉。不过当corePoolSize=maxPoolSize时,keepAliveTime参数也就不起作用了(因为不存在非核心线程);
    unit:keepAliveTime的时间单位
    workQueue(工作队列):用于保存任务的队列,可以为无界、有界、同步移交三种队列类型之一,当池子里的工作线程数大于corePoolSize时,这时新进来的任务会被放到队列中
        SynchronousQueue(同步移交队列):队列不作为任务的缓冲方式,可以简单理解为队列长度为零
        LinkedBlockingQueue(无界队列):队列长度不受限制,当请求越来越多时(任务处理速度跟不上任务提交速度造成请求堆积)可能导致内存不足
        ArrayBlockintQueue(有界队列):队列长度受限,当队列满了就需要创建多余的线程来执行任务
    threadFactory(线程工厂):创建线程的工厂类,默认使用Executors.defaultThreadFactory(),也可以使用guava库的ThreadFactoryBuilder来创建
    handler(拒绝策略):线程池满载(队列数已满且线程数=maximunPoolSize)的时候,执行的拒绝接收任务的策略,取值有AbortPolicy、DiscardPolicy、DiscardOldestPolicy、CallerRunsPolicy
        AbortPolicy:默认方式,拒绝新任务并抛出RejectedExecutionException异常
        DiscardPolicy:什么也不做,直接忽略
        DiscardOldestPolicy:废弃队列中最老任务,接收当前任务。
        CallerRunsPolicy:直接由提交任务者执行这个任务
三、线程池的关闭
    shutdownNow():立即关闭线程池,正在执行中的及队列中的任务会被中断,同时该方法会返回被中断的队列中的任务列表
    shutdown():平滑关闭线程池,正在执行中的及队列中的任务能执行完成,后续进来的任务会被执行拒绝策略
    isTerminated():当正在执行的任务及对列中的任务全部都执行(清空)完就会返回true

四、线程池中线程数量定义
    线程池中,最核心的两个参数:核心线程数(corePoolSize)和最大线程数(maximumPoolSize)的数量设置
    核心线程数:
        CPU密集型任务:
            比如加解密、压缩、计算等,需大量消耗CPU资源的任务,最佳的线程数为 CPU 核心数的 1~2 倍
        耗时I/O型任务:
            比如数据库读取、文件读写、网络通信等,不会特别消耗CPU资源,但是总体耗时较多的任务
                线程数=CPU核心数*(1+平均等待时间/平均工作时间)
            单线程平均工作时间长,线程数相应减少。单线程平均工作时间越短,线程数相应增加。
五、线程工厂
    通过线程工厂给每个创建出来的线程设置极富业务含义的名字,实现业务上的肉眼区分

    通过第三方jar实现
    Spring下的CustomizableThreadFactory:Spring框架提供
        ThreadFactory springFactory = new CustomizableThreadFactory("spring-pool-");
        ExecutorService exec = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue(100), springFactory);

    guava下的ThreadFactoryBuilder:Google 开源框架guava提供
        ThreadFactory guavaFactory = new ThreadFactoryBuilder().setNameFormat("guava-pool-").build();
        ExecutorService exec = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue(100), guavaFactory);

    Apache下的commons-lang3 BasicThreadFactory:Apache提供。
        ThreadFactory apacheFactory = new BasicThreadFactory.Builder().namingPattern("apache-pool-").build();
        ExecutorService exec = new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue(100), apacheFactory);

    自定义ThreadFactory
        实现ThreadFactory接口,赋予线程名称属性。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/957165.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号