美文网首页
Java线程池使用不当引发的阻塞问题

Java线程池使用不当引发的阻塞问题

作者: 爱的旋转体 | 来源:发表于2022-07-14 15:34 被阅读0次

将下面TestThreadPool代码中改为使用同一个线程池即可复现问题。
注:可以调用CompletableFuture的带超时时间的get方法,避免长时间执行等待。


image.png

1、引入guava依赖

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>

2、代码示例

package com.example.demo;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThreadPool {

    private static final ThreadPoolExecutor MAIN_THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), new ThreadFactoryBuilder().setNameFormat("main-pool-thread-%d").build(), new ThreadPoolExecutor.CallerRunsPolicy());
    private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), new ThreadFactoryBuilder().setNameFormat("sub-pool-thread-%d").build(), new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) {
        System.out.println("start------------");
        try {
            List<CompletableFuture<Integer>> list = new ArrayList<>();
            for(int i = 1; i <= 3; i++){
                list.add(getMainCompletableFuture("主任务"+i));
            }
            CompletableFuture.allOf(list.toArray(new CompletableFuture[0])).get();
        } catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("end------------");
        MAIN_THREAD_POOL_EXECUTOR.shutdown();
        THREAD_POOL_EXECUTOR.shutdown();
    }

    public static CompletableFuture<Integer> getMainCompletableFuture(String name){
        return CompletableFuture.supplyAsync(() -> {
            System.out.println(name+",开始--" + Thread.currentThread().getName());
            Integer res = getSubTask(name);
            System.out.println(name+",结束--" + Thread.currentThread().getName());
            return res;
        },MAIN_THREAD_POOL_EXECUTOR);
    }

    public static Integer getSubTask(String parentName) {
        try {
            List<CompletableFuture<Integer>> list = new ArrayList<>();
            for(int i = 1; i <= 3; i++){
                list.add(getSubCompletableFuture(parentName+"-子任务"+i));
            }
            CompletableFuture.allOf(list.toArray(new CompletableFuture[0])).get();
        } catch (Exception e){
            e.printStackTrace();
        }
        return 1;
    }

    public static CompletableFuture<Integer> getSubCompletableFuture(String name){
        return CompletableFuture.supplyAsync(() -> {
            System.out.println(name + ",开始--" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name + ",结束--" + Thread.currentThread().getName());
            return 1;
        },THREAD_POOL_EXECUTOR);
    }
}
image.png

相关文章

  • Java线程池使用不当引发的阻塞问题

    将下面TestThreadPool代码中改为使用同一个线程池即可复现问题。注:可以调用CompletableFut...

  • Android基础(25)多线程(三) 线程池

    1)Java多线程引发的性能问题,怎么解决?2)线程池 。线程池有没有上限?3)Android线程有没有上限?4)...

  • 我们的线程被饿死了

    我们的线程被饿死了 我们在构建线程池的时候可以构建单个线程的线程池和多个线程的线程池。 那么线程池使用不当可不可能...

  • Java相关面试问题

    线程,多线程,线程池的那些事 Java中的线程的生命周期大体可分为5种状态:新建、可运行、运行、阻塞、死亡。 1、...

  • ReentranLock底层原理分析

    1 J.U.C简介 java.util.concurrent 简称,java并发工具包 线程池 阻塞队列 计时器/...

  • Java线程池总结

    本篇文章讲述Java中的线程池问题,同样适用于Android中的线程池使用。本篇文章参考:Java线程池分析,Ja...

  • Java线程池详解

    本篇文章讲述Java中的线程池问题,同样适用于Android中的线程池使用。本篇文章参考:Java线程池分析,Ja...

  • 线程池

    线程池执行过程 线程池生命周期 线程池分类 阻塞队列 拒绝策略 - ThreadPoolExecutor.Abor...

  • Java线程池submit阻塞获取结果实现原理

    Java线程池中提交任务运行,通常使用execute()方法就足够了。那如果想要实现在主线程中阻塞获取线程池任务运...

  • J.U.C——线程池专题

    主要讨论以下问题: 认识Java线程池 线程池的种类,区别,和使用场景 线程池的工作流程 线程池几个参数的理解 分...

网友评论

      本文标题:Java线程池使用不当引发的阻塞问题

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