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

经核查,该问题是由于立单接口内部没有成功调用接续的 “更新来电原因接口”导致的,接续测更新来电原因接口编码: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. .NET上传大文件时提示Maximum request length exceeded错误的解决方法

    使用IIS托管应用程序时,当我们需要上传大文件(4MB以上)时,应用程序会提示Maximum request length exceeded的错误信息.该错误信息的翻译:超过最大请求长度. 解决方法: ...

  2. IIS 网站 HTTP 转 HTTPS

    最近需要做 http 链接转成 https 链接,所以就去弄了,现在记录下: 1.准备SSL证书 最开始的时候用的是腾讯云的免费证书,有效期1年,但只能绑定一个二级域名.测试成功后,就去阿里云购买了证 ...

  3. 如何禁用package-lock

    因为 package-lock.json是自动生成的,可以配置 npm 来避免经常需要手动删除这个文件. 在当前项目禁用 package-lock.json 控制台下输入 echo 'package- ...

  4. [oracle] Oracle存储过程里操作BLOB的字节数据的办法,例如写入32位整数

    作者: zyl910 一.缘由 BLOB是指二进制大对象,也就是英文Binary Large Object的缩写. 在很多时候,我们是通过其他编程语言(如Java)访问BLOB的字节数据,进行字节级的 ...

  5. 【mysql】不可不知的Metadata Lock

    一.问题发生 说一个现象,当收到服务器报警之后,数据库服务器CPU使用超过90%,通过 show processlist 一看,满屏都是 Waiting for table metadata lock ...

  6. 网页出现400 Bad Request Request Header Or Cookie Too Large错误的解决方法

    在开发项目过程中,突然遇到400 Bad Request Request Header Or Cookie Too Large的报错,我也是第一次出现这样的错误,感觉还是挺新奇的. 分析下出现错误的原 ...

  7. 【python】Python的安装和配置

    Python是一种计算机程序设计语言.是一种动态的.面向对象的脚本语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的开发. Pyt ...

  8. linux下 彻底修改python的包/模块导入路径

    python模式下,有时候需要导入  import某些模块或者包.明明这个模块/包是存在的,却提示导入错误,比如,“ImportError: No module named lxml”. 但是当你在命 ...

  9. [转]Redis cluster failover

    今天测试了redis cluster  failover 功能,在切换过程中很快,但在failover时有force 与takeover 之分 [RHZYTEST_10:REDIS:6237:M ~] ...

  10. LaTeX网址

    https://www.latex-project.org/   latex官网 http://www.latexstudio.net/   国内知名latex学习中心 https://www.ove ...