zoukankan      html  css  js  c++  java
  • Java并发编程(十一)线程池的使用

     1.new Thread的弊端如下:

    • a. 每次new Thread新建对象性能差。
    • b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
    • c. 缺乏更多功能,如定时执行、定期执行、线程中断。

    相比new Thread,Java提供的四种线程池的好处在于:

    • a.重用线程池中存在的线程,避免因为线程的大量创建和销毁所带来的性能开销 ,完成一项任务的时间T=创建线程的时间+在线程中执行任务的时间+线程销毁的时间, 而线程池的出现可以大大减少创建线程的时间和线程销毁的时间,从而提高app的性能
    • b.能有限的控制线程池的最大并发数,并且大量的线程互相抢占资源而导致的阻塞现象
    • c.对线程池中线程进行有效的跟进,当我们不需要处理的时候可以将它shutdow掉,并提供定时执行以及制定间隔循环执行,

      

    2、Java 线程池

    Java通过Executors提供四种线程池,分别为:
    CachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。在线程空闲60秒后终止线程。
    FixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    ScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
    SingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

    Executors类用于管理Thread对象,简化并发过程,我们可以看到FixedThreadPool的创建过程:

    public static ExecutorService newFixedThreadPool(int nThreads) {  
        return new ThreadPoolExecutor(nThreads, nThreads,   
                                     0L, TimeUnit.MILLISECONDS,  
                                      new LinkedBlockingQueue<Runnable>());  
    }  

    显然这四种线程池方法都是返回实现了ExecutorService接口的ThreadPoolExecutor。当然我们也可以直接用ThreadPoolExecutor来自定义更灵活的线程池。

     

    我们先看看ThreadPoolExecutor的构建参数:

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

    当池子大小小于corePoolSize就新建线程,并处理请求,当池子大小大于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去从workQueue中取任务并处理,当workQueue放不下新入的任务时,新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize就用RejectedExecutionHandler来做拒绝处理。另外,当池子的线程数大于corePoolSize的时候,多余的线程会等待keepAliveTime长的时间,如果无请求可处理就自行销毁

    接下来我们来看看CachedThreadPool:

    public static ExecutorService newCachedThreadPool() {  
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,  
                                     60L, TimeUnit.SECONDS,  
                                      new SynchronousQueue<Runnable>());  
    }  

    CachedThreadPool在程序执行时会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此是Executor的首选,只有当这种方式会引发问题,或者不符合业务需要时才采用另外的三种Executor提供的线程池

    SingleThreadExecutor 就是线程数量为1的FixedThreadPool,如果向SingleThreadExecutor提交多个任务,那么这些任务会排队,每个任务都会在下个任务开始之前就结束,所有任务都用一个线程,并且按照提交的顺序执行。

     线程池用于线程数量比较多时的场景,如果只开启2,3个线程就用线程池,显然会极度的浪费资源

    http://www.cnblogs.com/dolphin0520/p/3932921.html

    https://blog.csdn.net/qq_31694651/article/details/52184663

  • 相关阅读:
    HUST 1372 marshmallow
    HUST 1371 Emergency relief
    CodeForces 629D Babaei and Birthday Cake
    CodeForces 629C Famil Door and Brackets
    ZOJ 3872 Beauty of Array
    ZOJ 3870 Team Formation
    HDU 5631 Rikka with Graph
    HDU 5630 Rikka with Chess
    CodeForces 626D Jerry's Protest
    【POJ 1964】 City Game
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/6169354.html
Copyright © 2011-2022 走看看