线程调度-线程池

一、new Thread弊端

    1.每次new Thread新建对象,性能查。
    2.线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致司机或OOM(Out Of Memory)。
    3.缺少更多的功能,如更多执行、定期执行、线程中断。

二、线程池的好处

    1.重用存在的线程,减少对象创建、消亡的开销,性能好。
    2.可有效控制最大并发线程数,提高系统资源利用率,同时可以避免过多资源竞争,避免阻塞。
    3.提供定时执行、定期执行、单线程、并发数控制等高级功能。

三、线程池相关的类

    1.ThreadPoolExecutor
        ThreadPoolExecutor中含有三个参数
        1)corePoolSize:核心线程数量。
        2)maximumPoolSize:最大线程数。
        3)workQueue:阻塞队列,存储等待执行的任务,很重要,会对线程池运行过程产生重大影响。常用的有三种队列,SynchronousQueue,LinkedBlockingDeque,ArrayBlockingQueue
        4)KeepAliveTime:非核心线程没有任务执行时最多保持多长时间终止。
        5)unit:keepAliveTime的时间单位。
        6)threadFactory:线程工厂,用来创建线程。
        7)rejectHandler:拒绝处理任务时的策略。
        8)线程池规则
            下面都假设任务队列没有大小限制:
            a.如果线程数量<=核心线程数量,那么直接启动一个核心线程来执行任务,不会放入队列中。           
            b.如果线程数量>核心线程数,但<=最大线程数,并且任务队列是LinkedBlockingDeque的时候,超过核心线程数量的任务会放在任务队列中排队。
            c.如果线程数量>核心线程数,但<=最大线程数,并且任务队列是SynchronousQueue的时候,线程池会创建新线程执行任务,这些任务也不会被放在任务队列中。这些线程属于非核心线程,在任务完成后,闲置时间达到了超时时间就会被清除。        
            d.如果线程数量>核心线程数,并且>最大线程数,当任务队列是LinkedBlockingDeque,会将超过核心线程的任务放在任务队列中排队。也就是当任务队列是LinkedBlockingDeque并且没有大小限制时,线程池的最大线程数设置是无效的,他的线程数最多不会超过核心线程数。
            e.如果线程数量>核心线程数,并且>最大线程数,当任务队列是SynchronousQueue的时候,会因为线程池拒绝添加任务而抛出异常。
            任务队列大小有限时
           a.当LinkedBlockingDeque塞满时,新增的任务会直接创建新线程来执行,当创建的线程数量超过最大线程数量时会抛异常。
           b.SynchronousQueue没有数量限制。因为他根本不保持这些任务,而是直接交给线程池去执行。当任务数量超过最大线程数时会直接抛异常。
        9)线程池的使用:
            a.execute():提交任务,交给线程池执行。
            b.submit():提交任务,能够返回结果(execute+Future)。
            c.shutdown():关闭线程池,等待任务都执行完毕。
            d.shutdownNow():关闭线程池,不等待任务执行完毕,会中断正在执行的线程。
            e.getTaskCount():线程池已执行和未执行的任务总数。
            f.getCompletedTaskCount():已完成的任务数量。
            g.getPoolSize():线程池当前的线程数量。
            h.getActiveCount():当前线程池中正在执行任务的线程数量。
    2.Executor框架提供的四种线程池
        executor框架提供了四种线程池,其内部都是返回一个ThreadPoolExecutor对象。
       1)Executors.newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。(线程最大并发数不可控制)
        2)Executors.newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
        3)Executors.newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
        4)Executors.newSingleThreadPool:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

    3.线程池的合理配置
        1)CPU密集型任务,就需要尽量压榨CPU,参考值可以尽量设置为CPU数量+1。
        2)IO密集型任务,参考值可以设置为2*CPU数量。
注:使用线程池也需要慎重,有些场景下因为线程池中任务调度所造成的开销,可能会使我们得不偿失。
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值