关于新疆服务请求未带入来话原因的问题

经核查,该问题是由于立单接口内部没有成功调用接续的 “更新来电原因接口”导致的,接续测更新来电原因接口编码:NGCCT_UPDATESRFLAG_PUT ,立单接口调用代码如下:

final Map<String, Object> paramsMap = outputObject.getBean();
paramsMap.put("provCode", provCode);
paramsMap.put("tenantId", MapUtils.getString(inputObject.getParams(), "tenantId"));
TaskEngine.getInstance().submit(new Runnable() {
@Override
public void run() {
callContactRel(paramsMap);[zhai1]
backWriteWrkfm(paramsMap);
}
});

立单接口中使用起多线程异步调用方式,更新来电原因方法内部记录日志,由于线程内部日志无法在火眼系统查看,当出现该问题时,

1.多次找在线运维人员查看主机上的日志,均未发现更新来话原因方法内部记录的日志;

2.登陆csf平台查询该接口的调用记录,根据出现问题的流水号均未查到相关调用记录;

3.核查调用更新来电原因方法内部catch中如表的错误记录,也未发现问题;

根据火眼上上下文日志,确定程序一定运行到了启动多线程的地方,遂怀疑线程池的问题,

该处启用多线程使用的是 TaskEngine工具提供的获取线程池,使用池中资源执行任务。

经核查TaskEngine类发现该类在初始化的时候会创建一个线程池,核心线程数为1,最大线程数为30的线程池,代码如下:

private static TaskEngine instance = new TaskEngine();
public static TaskEngine getInstance() { return instance; }
private TaskEngine() { executor = new ThreadPoolExecutor(1, 30,180L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ThreadFactory() { final AtomicInteger threadNumber = new AtomicInteger(1); public Thread newThread(Runnable runnable) { // Use our own naming scheme for the threads. Thread thread = new Thread(Thread.currentThread().getThreadGroup(), runnable, "TaskEngine-pool-" + threadNumber.getAndIncrement(), 0); // Make workers daemon threads. thread.setDaemon(true); if (thread.getPriority() != Thread.NORM_PRIORITY) { thread.setPriority(Thread.NORM_PRIORITY); }
return thread;
}
});
}

该线程池构造时尚未指明 拒绝策略 [zhai2] 因此会默认使用 AbortPolicy

JDK提供的ThreadPoolExecutor 线程池有四种 拒绝策略:

AbortPolicy 当任务添加到线程池中被拒绝时,它将抛出 RejectedExecutionException 异常。

CallerRunsPolicy 当任务添加到线程池中被拒绝时,会在线程池当前正在运行的Thread线程池中处理被拒绝的任务。

DiscardOldestPolicy 当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中。

DiscardPolicy 当任务添加到线程池中被拒绝时,线程池将丢弃被拒绝的任务。

工程中使用的默认的策略,会不会存在一种情况,在某一个时刻,使用TaskEngine类获取线程池来执行任务时,30个线程同时被使用,导致创建任务数大于最大线程数的限制,该任务将无法被成功执行。

Demo验证:

1.使用与项目中相同的线程池执行数据入库操作,模拟设置最大线程数10,核心线程1个,拒绝策略默认:

@RequestMapping(value = "/testThread")

public String testThread(){

    final CommonCfgCode commonCfgCode = new CommonCfgCode();

    commonCfgCode.setCodeTypeCd("Thread");

    TaskEngine taskEngine = TaskEngine.getInstance();

    for(int i=0;i<100;i++){

        taskEngine.submit(new Runnable() {

            @Override

            public void run() {

                testService.save(commonCfgCode);

            }

        });

    }

    return "SUCCESS";

}

循环执行100个任务进行如表操作抛出:

java.util.concurrent.RejectedExecutionException异常,与该策略描述一致。

查看如表数据:仅如表10条数据;

2.将拒绝策略修改为:CallerRunsPolicy 其它不变;

无报错,查询数据:如表100条;(110条中包含使用默认拒绝抛异常策略如表的10条)

Demo git路径:https://git.lug.ustc.edu.cn/zhaiyt/mylife.git

由于该问题仅在新疆出现,出现的场景无法预知,请各位评审是否可以修改项目中TaskEngine类。


[zhai1]调用接续接口更新来话原因方法

[zhai2]线程池的拒绝策略,是指当任务添加到线程池中被拒绝,而采取的处理措施。当任务添加到线程池中之所以被拒绝,可能是由于:第一,线程池异常关闭。第二,任务数量超过线程池的最大限制

JDK线程池的拒绝策略的更多相关文章

  1. Java线程池的拒绝策略

    一.简介 jdk1.5 版本新增了JUC并发编程包,极大的简化了传统的多线程开发.前面文章中介绍了线程池的使用,链接地址:https://www.cnblogs.com/eric-fang/p/900 ...

  2. dubbo线程池的拒绝策略

    jdk自带的原生的拒绝策略抛出的异常信息不够详细,而dubbo对拒绝策略进行了改写,抛出的信息更具有参考价值,值得我们借鉴. jdk自带的原生拒绝策略抛出的信息: // ThreadPoolExecu ...

  3. Dubbo里面线程池的拒绝策略

    Dubbo里面线程池的拒绝策略 public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy { protecte ...

  4. SimpleThreadPool给线程池增加拒绝策略和停止方法

    给线程池增加拒绝策略和停止方法 package com.dwz.concurrency.chapter13; import java.util.ArrayList; import java.util. ...

  5. Java - "JUC线程池" 线程状态与拒绝策略源码分析

    Java多线程系列--“JUC线程池”04之 线程池原理(三) 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基本概念"中,我们介绍过,线程有5种状态:新建 ...

  6. java并发:线程池、饱和策略、定制、扩展

    一.序言 当我们需要使用线程的时候,我们可以新建一个线程,然后显式调用线程的start()方法,这样实现起来非常简便,但在某些场景下存在缺陷:如果需要同时执行多个任务(即并发的线程数量很多),频繁地创 ...

  7. JDK线程池和Spring线程池的使用

    JDK线程池和Spring线程池实例,异步调用,可以直接使用 (1)JDK线程池的使用,此处采用单例的方式提供,见示例: public class ThreadPoolUtil { private s ...

  8. JDK线程池

    简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力,但频繁的创建线程的开销是很大的,那么如何来减少这部分的开销了,那么就要考虑使用线程 ...

  9. JDK 线程池

    JDK 线程池 线程池参数 在JDK的4种线程池之前, 先介绍一下线程池的几个参数 corePoolSize 线程池的核心线程数量, maximumPoolSize 线程池的最大线程数量 keepAl ...

随机推荐

  1. 罗技Setpoint控制酷狗等第三方播放器

    手里有个淘过来的二手戴尔蓝牙键盘,虽然是戴尔的,但是确实罗技代工的,因此可以使用罗技的Setpoint,用这个软件后可以集中管理罗技的键盘鼠标进行一些个性化设置,如下图所示.不过郁闷的是如果不装Set ...

  2. Spark(四十五):Schema Registry

    很多时候在流数据处理时,我们会将avro格式的数据写入到kafka的topic,但是avro写入到kafka的时候,数据有可能会与版本升级,也就是schema发生变化,此时如果消费端,不知道哪些数据的 ...

  3. mac下安装xampp、及其之上的组件安装

    由于mac下开发需要用到php7,这里是用的xampp集成开发版本.但是mac下安装xampp失败,失败信息如下: Error starting "XAMPP" stack: fa ...

  4. php5.6.11编译安装报错configure: error: Don't know how to define struct flock on this system

    centos 6.8 32位系统下,安装php.5.6.11是出现这个错误 解决办法: 1 2 3 4 vim /etc/ld.so.conf.d/local.conf     # 编辑库文件 /us ...

  5. PHP-问题处理验证码无法显示出来

    1.问题 今天重新安装了ubuntu,PHP,MySQL,Apache,到测试CMS项目时发生一个错误: 验证码无法显示出来. 2.解决: 2.1 使用 phpinfo检查: phpinfo(); 在 ...

  6. Atitit php java python nodejs错误日志功能的比较

    Atitit php  java  python  nodejs错误日志功能的比较 1.1. Php方案 自带 1 1.2. Java解决方案 SLF4J 1 1.3. Python解决方案 自带lo ...

  7. 微信公众号平台上传文件返回错误代码:40005 invalid file type

    错误原因:文件类型(后缀名)不符合要求. 具体到笔者的情况是:在将 MultipartFile 类型转换为File 类型时,方法 File.createTempFile("filename& ...

  8. MVC教程四:Controller向View传值的几种方式

    一.通过ViewData传值 MVC从开始版本就一直支持使用ViewData将Controller里面的数据传递到View.ViewData定义如下: 从上面的截图中可以看出,ViewData里面存的 ...

  9. python 文档

    python 文档 https://docs.python.org/2/library/index.html

  10. C++中常用的std标准容器

    从c++11标准以来,c++中std定义的几种容器的效率非常高,优化的非常好,完全没有必要自己去定义类似的数据结构.了解使用它们,可以满足90%的日常编程需要.该篇文章基于c++11标准,从用户角度来 ...