线程池

线程池

项目文件:HelloJava-ThreadPoolExecutorDemo

  1. 线程池优点:

    • 重用线程,避免创建和销毁线程的性能开销;
    • 有效控制线程池最大并发数,避免大量线程之间因互相抢占系统资源而导致的阻塞现象;
    • 能对线程进行简单管理,并提供定时执行已经间隔循环执行等功能;
  2. 继承关系:源于Executor;真正实现是ThreadPoolExecotor;

    public interface Executor {
        void execute(Runnable command);
    }
    public interface ExecutorService extends Executor {...}
    public abstract class AbstractExecutorService implements ExecutorService {...}
    public class ThreadPoolExecutor extends AbstractExecutorService {...}
    
  3. ThreadPoolExecutor

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue
                              ThreadFactory threadFactory
                              RejectedExecutionHandler handler){
        ...
        private volatile boolean allowCoreThreadTimeOut;
        ...
    }
    
    • corePoolSize:核心线程数,核心线程会在线程池中一直存活。如果allowCoreThreadTimeOut为true,闲置的核心线程等待时长超过keepAliveTIme所指定的时长,核心线程会被终止;

    • maximumPoolSize:线程池所能容纳的最大线程数;

    • keepAliveTime非核心线程闲置的超时时长,超过时长,非核心线程被回收;如果allowCoreThreadTimeOut为true,同样作用于核心线程;

    • unit: keepAliveTime参数的时间单位,枚举值,常用TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS、TimeUnit.MINUTES;

    • workQueue:任务队列,通过线程execute方法提交的Runnable对象会存储在这个参数中;

    • threadFactory:线程工厂,为线程池提供创建新线程的功能。

      public interface ThreadFactory {
          Thread newThread(Runnable r);
      }
      
    • RejectedExecutionHandler handler:当线程池无法执行新任务,如任务队列已满或者无法成功执行任务,会调用handler.rejectedExecution,默认抛出异常。

  4. ThreadPoolExecutor执行流程:

    • 先开核心线程
    • 填充任务队列
    • 任务队列满了但未达到maximumPoolSize,再开非核心线程
    • 线程池数量达到线程池规定的最大值maximumPoolSize,handler抛出异常;
  5. 线程池分类:

    • FixedThreadPool:线程数量固定,只有核心线程且不会被回收;任务队列没有大小限制;

       public static ExecutorService newFixedThreadPool(int nThreads) {
           return new ThreadPoolExecutor(nThreads, nThreads,
                                         0L, TimeUnit.MILLISECONDS,
                                         new LinkedBlockingQueue<Runnable>());
       }
      
    • CachedThreadPool:只有非核心线程,线程数量不定;超时60s回收;SynchronousQueue可以理解为无法存储元素的队列;适合执行大量的耗时少的任务,当线程池闲置时,线程都会被超时回收,几乎不占用系统资源;

      public static ExecutorService newCachedThreadPool() {
          return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                        60L, TimeUnit.SECONDS,
                                        new SynchronousQueue<Runnable>());
      }
      
    • ScheduledThreadPool:核心线程固定,非核心线程没有限制,非核心线程闲置立即回收(keepAliveTime为0);主要执行定时任务周期任务;schedule:计划(表),进度表,调度。

      public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
          return new ScheduledThreadPoolExecutor(corePoolSize);
      }
      
      public ScheduledThreadPoolExecutor(int corePoolSize) {
          super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
                new DelayedWorkQueue());
      }
      
    • SingleThreadPool只有一个核心线程;所有任务统一到一个线程,不需要处理线程同步问题。

      public static ExecutorService newSingleThreadExecutor() {
          return new FinalizableDelegatedExecutorService
              (new ThreadPoolExecutor(1, 1,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>()));
      }
      
  6. 通过Executors来创建线程池;(非Executor)

    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
    fixedThreadPool.execute(runnable);
    
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    cachedThreadPool.execute(runnable);
    
    ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
    scheduledThreadPool.execute(runnable);
    
    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    singleThreadExecutor.execute(runnable);
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容