java 线程池概述

作者: David_jim | 来源:发表于2018-03-09 12:55 被阅读86次

首先说明下为什么要写这篇文章,最近在查一个前负责人留下的一个Hbase中的数据问题,是为了记录前端的行为记录,做法是在服务端开了一个接口来接收前端的请求,这个接口的请求实作是在服务端开了一个线程池来处理写入Hbase的动作,但经常会发现有些数据会丢失,也没有日志

线程池定义代码如下:

 Executor executor = new ThreadPoolExecutor(32, 128, 0, TimeUnit.DAYS, new ArrayBlockingQueue(1024));

上面是线程池的构造方式,首先来了解下这个构造函数中的参数的定义

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
            this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            Executors.defaultThreadFactory(), defaultHandler);
} 
参数定义
  1. corePoolSize 在线程池中一直存在的线程数,即使是空闲的
  2. maximumPoolSize 线程池的最大线程数
  3. keepAliveTime 当线程池中的线程数大于 corePoolSize ,空闲的线程在被销毁前会在线程池中保留的最大时间
  4. unit keepAliveTime 的时间单位
  5. workQueue 当线程池中的线程数大于maximumPoolSize ,会把后续的线程放入队列中
  6. threadFactory 线程工厂
  7. RejectedExecutionHandler 线程队列的拒绝策略
    • AbortPolicy(默认策略) 如果线程队列满了,则会丢弃当前任务,并抛出异常RejectedExecutionException
    • DiscardPolicy 如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常。
    • DiscardOldestPolicy 如果队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列
    • CallerRunsPolicy 如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行

再结合前言和参数定义中可以知道,创建的线程池中,传的BlockingQueue是ArrayBlockingQueue

BlockingQueue

BlockingQueue是阻塞队列接口,我们介绍三个实现

  • ArrayBlockingQueue(有界队列)
  • LinkedBlockingDeque(可选边界)
  • SynchronousQueue

SynchronousQueue 的描述
有多个生产者,可以并发生产产品,把产品置入队列中,如果队列满了,生产者就会阻塞;
有多个消费者,并发从队列中获取产品,如果队列空了,消费者就会阻塞;

ArrayBlockingQueue 是一个有界队列,超过这个队列的容量,则后续的数据就不允许再添加,那这个对于我们开始说的那个问题,就会有影响了,在线程池中的线程数量超过128(max)+1024(workQueue)的大小后,就会执行RejectedExecutionHandler 的内容了
因为当前这个问题是一个会有大并发量进来记录行为日志,肯定会超过这个范围的,而且终端用户也是一个大量级的,所以对于会丢失数据,也就不足为奇了
那这个问题目前有两个想法:

  1. 调整BlockingQueue 为LinkedBlockingDeque
  2. 对于进来的数据,用消息队列进行处理(redis,mq)都可以作为参考
    后续文章会继续这方面的学习

相关文章

  • 线程池底层原理

    概述 JAVA通过多线程的方式实现并发,为了方便线程池的管理,JAVA采用线程池的方式对线线程的整个生命周期进行管...

  • Java:线程池Executors.newFixedThread

    摘要:Java,多线程,线程池 多线程编程和线程池概述 (1)多线程程序: 计算机可以实现多任务 ( multit...

  • JAVA基础之并发

    1、概述 Java5中对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还...

  • java 线程池概述

    首先说明下为什么要写这篇文章,最近在查一个前负责人留下的一个Hbase中的数据问题,是为了记录前端的行为记录,做法...

  • Java 线程池概述

  • 多线程之线程池

    今天学习了线程池。java有各种池,对于初学者而言听着都头疼。下面我们来了解一下什么是线程池。一:线程池的概述试想...

  • Java再回顾(1)—线程池回顾与思考

    概述 本文是针对java线程池的回顾与思考,主要是围绕java线程池的思路梳理与知识总结。长文预警(写这篇真的累到...

  • Java 线程池

    1、概述 Java中的关于线程池的核心类是Executor,Executor是一个接口,真正的线程池的实现为Thr...

  • 分析jdk-1.8-ForkJoinPool实现原理(上)

    Java并发编程源码分析系列: 分析Java线程池的创建 分析Java线程池执行原理 分析Java线程池Calla...

  • 分析jdk-1.8-ForkJoinPool实现原理(下)

    Java并发编程源码分析系列: 分析Java线程池的创建 分析Java线程池执行原理 分析Java线程池Calla...

网友评论

    本文标题:java 线程池概述

    本文链接:https://www.haomeiwen.com/subject/pdfpfftx.html