相关文章推荐

2019-08-07 工作中遇到的问题

事件情况描述: 有个线程池满了,然后新的任务使用 CompletableFuture.supplyAsync 执行,用 future.get(1, TimeUnit.SECONDS)) 去获取(即使把get事件设置的很大)时报错 java.util.concurrent.TimeoutException

报错 java.util.concurrent.TimeoutException 觉得很奇怪;随后debug发现 CompletableFuture.supplyAsync 的执行任务压根儿没执行;最后是调整了线程池解决

线程池满了,线程池被耗完了: 1,同时运行当任务太多,确实没有多的了;2,有耗时的任务,即使用个异步任务,也无法执行

  • 复现代码 1
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
 * @Author mubi
 * @Date 2019/8/5 14:27
public class Test{
    static class MyThreadFactory implements ThreadFactory {
        private AtomicInteger count = new AtomicInteger(0);
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            String threadName = "MyThread" + count.addAndGet(1);
            // System.out.println(threadName);
            t.setName(threadName);
            return t;
    static String printHello(){
        return "hello";
    public static void main(String[] args) {
        int corePoolSize = 1;
        int maximumPoolSize = 2;
        int keepAliveTime = 60 * 1;
        TimeUnit timeUnit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
//        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadFactory threadFactory = new MyThreadFactory();
        // 线程池构造
        ThreadPoolExecutor taskExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                timeUnit,
                workQueue,
                threadFactory,
                handler);
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                // 耗时操作,会沾满线程池
//                taskExecutor.execute(() -> {
//                    try {
//                        TimeUnit.SECONDS.sleep(10);
//                    }catch (Exception e){
//                        e.printStackTrace();
//                    }
//                });
                // 第二步不耗时的操作,但是get的时候会报TimeoutException
                CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(Test::printHello, taskExecutor);
                try {
                    System.out.println(Thread.currentThread().getName() + "::value1 " + future1.get(1, TimeUnit.SECONDS));
                } catch (Exception e) {
                    e.printStackTrace();
            }).start();
        try {
            TimeUnit.SECONDS.sleep(5000);
        }catch (Exception e){
            e.printStackTrace();

某次输出如下

Thread-9::value1 hello
Thread-3::value1 hello
Thread-2::value1 hello
Thread-8::value1 hello
java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at Main.lambda$main$1(Main.java:539)
	at java.lang.Thread.run(Thread.java:748)
java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at Main.lambda$main$1(Main.java:539)
	at java.lang.Thread.run(Thread.java:748)
java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at Main.lambda$main$1(Main.java:539)
	at java.lang.Thread.run(Thread.java:748)
java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at Main.lambda$main$1(Main.java:539)
	at java.lang.Thread.run(Thread.java:748)
java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at Main.lambda$main$1(Main.java:539)
	at java.lang.Thread.run(Thread.java:748)
java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at Main.lambda$main$1(Main.java:539)
	at java.lang.Thread.run(Thread.java:748)
  • 复现代码 2
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
 * @Author mubi
 * @Date 2019/8/5 14:27
public class Test{
    static class MyThreadFactory implements ThreadFactory {
        private AtomicInteger count = new AtomicInteger(0);
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            String threadName = "MyThread" + count.addAndGet(1);
            System.out.println(threadName);
            t.setName(threadName);
            return t;
    static String printHello(){
        return "hello";
    public static void main(String[] args) {
        int corePoolSize = 1;
        int maximumPoolSize = 2;
        int keepAliveTime = 60 * 1;
        TimeUnit timeUnit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
//        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadFactory threadFactory = new MyThreadFactory();
        // 线程池构造
        ThreadPoolExecutor taskExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                timeUnit,
                workQueue,
                threadFactory,
                handler);
        for (int i = 1; i < 3; i++) {
            new Thread(() -> {
                // 耗时操作,会沾满线程池
                taskExecutor.execute(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(10);
                    }catch (Exception e){
                        e.printStackTrace();
                });
                // 第二步不耗时的操作,但是get的时候会报TimeoutException
                CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(Test::printHello, taskExecutor);
                try {
                    System.out.println(Thread.currentThread().getName() + "::value1 " + future1.get(1, TimeUnit.SECONDS));
                } catch (Exception e) {
                    e.printStackTrace();
            }).start();
        try {
            TimeUnit.SECONDS.sleep(5000);
        }catch (Exception e){
            e.printStackTrace();
Thread-0::value1 hello
java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at Main.lambda$main$2(Main.java:539)
	at java.lang.Thread.run(Thread.java:748)
                    2019-08-07 工作中遇到的问题大概是: 有个线程池满了,然后新的任务使用CompletableFuture.supplyAsync执行,用future1.get(1, TimeUnit.SECONDS)) 去获取的时候报错java.util.concurrent.TimeoutException报错java.util.concurrent.TimeoutException觉得很奇怪;随...
java.util.concurrent.TimeoutExceptionjava.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
处为null。 concurrent.CompletableFuture.get(CompletableFuture.java:1915)
					
Spark——成功解决java.util.concurrent.TimeoutException: Futures timed out after [600 seconds]
产生错误的代码段: CompletableFuture<Void> addressFuture1 = CompletableFuture.runAsync(() -> { //处理国籍信息 dealNationality(tbProfessionPageInfo.getList()); }, executor); 由于dealNationality方法通过fegin调用基础信息服务模块,但是因为加了异步之后产生了空指针异常
在jdk5中,我们通过使用Future和Callable,可以在任务执行完毕后得到任务执行结果。可以使用isDone检测计算是否完成,使用cancle停止执行任务,使用阻塞方法get阻塞住调用线程来获取返回结果,使用阻塞方式获取执行结果,有违异步编程的初衷,而且Future的异常只能自己内部处理。 jdk8中加入了实现类CompletableFuture<T>,用于异步编程。底层做任务使用的是ForkJoin, 顾名思义,是将任务的数据集分为多个子数据集,而每个子集,都可以由独立的子任 增加超时时间 增加了10 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 10000 关闭超时发生的异常 hystrix.command.default.execution.timeout.enabled=false 禁用Feign里面的Hystrix
CompletableFuture优化接口性能案例需求背景解决方案 在教育中心所有课程详情页都大致包含下面这么些,每种卡片的数据可能来自不同的数据源。数据源可能就是缓存数据,也可能是第三方的接口返回数据。因此对于这个接口一次性返回这么多卡片信息还是有点重的,我们尽量要使得每个卡片请求的数据要够快。对于头部影藏卡片而言,在数据适配阶段串行调用了三个第三方接口,而且每个接口最大超时时间outTime=200~300ms,对整个接口的性能还是有很大影响。 课程详情头部隐藏卡片,课程详情头部促销卡片,
在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring3.x之后,就已经内置了@Async来完美解决这个问题。 1.@Async介绍 在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无...
文章目录一、背景二、排查三、思考四、寻找答案-FUTURE五、寻找答案-线程池六、线程池拒绝异常 最近做一个技术优化的任务,然后发现有些数据并没有优化上,比如100个数据,但是只优化了98个。查看代码日志,无错,在数据库查询这个别数据,发现数据并无异常,应该也需要被优化。 通过arthas 的watch命令,观察个别数据的入参和返回。 watch com.xxx.service..impl.xx xxServiceImple o "{params,returnObj}" "params
22:22:44.234 [main] ERROR c.a.n.c.r.c.g.GrpcClient - [printIfErrorEnabled,99] - Server check fail, please check server ip ,port 9848 is available , error ={} java.util.concurrent.TimeoutException: Waited 3000 milliseconds (plus 8 milliseconds, 112600
 
推荐文章