多线程---线程池的使用

达梦数据库JDBC连接池断开自动重连设置 一、场景 在网络状况不是非常良好,经常会出现暂时性的拥塞或者断开的情况,而且当我们重启数据库时也会发生类似的情况。所以需要配置中间件的连接池来实现连接测试以及自动重连,通过重新配置连接池,成功解决了这个问题。下面会给出一份数据源配置参数详单和一份推荐的数据源配置项。 二、连接池配置参数 1. initialSize:连接池启动时创建的初始化连接数量 2. maxActive:连接池中可同时连接的最大的连接数 3. maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负 阅读详情

一、Executors - 线程池的工厂

在这里插入图片描述

二、JDK自带的一些线程池

1. SingleThreadExecutor

在这里插入图片描述

可以看到核心线程1个,最大线程同样也是1个,空闲等待时间为0毫秒, 即执行完本条任务后, 不继续原地等待,new LinkedBlockingQueue() 说明SingleThreadExecutor自己维护了一个链表阻塞队列, 无需手动去管理。

只有一个线程的线程池

为什么要有单线程的线程池?

  1. 线程池有属于自己的任务队列, 不需要自己去手动维护一个任务队列
  2. 有完整的生命周期管理
  • 代码演示
  /**
   * SingleThreadExecutor 只有一个线程的线程池
   */
  public class T07_SingleThreadPool {
      public static void main(String[] args) {
          ExecutorService service = Executors.newSingleThreadExecutor();
          for (int i = 0; i < 5; i++) {
              final int j = i;
              service.execute(() -> {
  
                  System.out.println(j + " " + Thread.currentThread().getName());
              });
          }
      }
  }
  • 输出结果

    0 pool-1-thread-1
    1 pool-1-thread-1
    2 pool-1-thread-1
    3 pool-1-thread-1
    4 pool-1-thread-1

2. FixThreadPool

在这里插入图片描述

固定数量线程的线程池, 构造函数只有一个参, 即线程数量

  • 代码演示

/**
 * FixedThreadPool 固定线程数量的线程池
 * 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
 * 定长线程池的大小最好根据系统资源进行设置
 */
public class T09_FixedThreadPool {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();
        //单线程执行统计1到200000之间的质数耗时
        getPrime(1, 200000);
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        //根据机器CPU 核数量
        final int cpuCoreNum = 4;

        //使用FixedThreadPool多线程执行,统计1到200000之间的质数耗时
        ExecutorService service = Executors.newFixedThreadPool(cpuCoreNum);

        MyTask t1 = new MyTask(1, 80000); //1-5 5-10 10-15 15-20
        MyTask t2 = new MyTask(80001, 130000);
        MyTask t3 = new MyTask(130001, 170000);
        MyTask t4 = new MyTask(170001, 200000);

        Future<List<Integer>> f1 = service.submit(t1);
        Future<List<Integer>> f2 = service.submit(t2);
        Future<List<Integer>> f3 = service.submit(t3);
        Future<List<Integer>> f4 = service.submit(t4);

        start = System.currentTimeMillis();
        f1.get();
        f2.get();
        f3.get();
        f4.get();
        end = System.currentTimeMillis();
        System.out.println(end - start);
        service.shutdown();
    }

    static class MyTask implements Callable<List<Integer>> {
        //起始数, 结束数
        int startPos, endPos;

        MyTask(int s, int e) {
            this.startPos = s;
            this.endPos = e;
        }

        @Override
        public List<Integer> call() {
            //统计质数
            List<Integer> r = getPrime(startPos, endPos);
            return r;
        }

    }

    static boolean isPrime(int num) {
        for (int i = 2; i <= num / 2; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }

    static List<Integer> getPrime(int start, int end) {
        List<Integer> results = new ArrayList<>();
        for (int i = start; i <= end; i++) {
            if (isPrime(i)) {
                results.add(i);
            }
        }

        return results;
    }
}

  • 输出结果

    2002
    716

3. CachedThreadPool

在这里插入图片描述

这里核心线程为0, 最大线程为Integer的最大值, 基本上无限大,等待队列采用的是SynchronousQueue(),对于SynchronousQueue,每次put进入一个任务后,必须有消费者进行消费才可以继续put,如果没有消费者, 则这里就会堵塞在这里。

  • 代码演示


/**
 * 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
 * 线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
 */
public class T08_CachedThreadPool {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService service = Executors.newCachedThreadPool();
        //初始化完成, 输出线程池基本信息
        System.out.println(service);
        for (int i = 0; i < 3; i++) {
            service.execute(() -> {
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            });
        }
        //打印线程池基本信息, 查看线程数,  活跃线程数, 等待队列任务数, 完成的队列任务数
        System.out.println(service);

        TimeUnit.SECONDS.sleep(800);

        System.out.println(service);


    }
}
  • 输出结果

    java.util.concurrent.ThreadPoolExecutor@60e53b93[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
    java.util.concurrent.ThreadPoolExecutor@60e53b93[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
    pool-1-thread-1
    pool-1-thread-2
    pool-1-thread-3

4. ScheduledThreadPool

在这里插入图片描述

5. WorkStealingPool

/**
 * WorkStealingPool每个线程都有自己单独的队列, 每个线程执行完自己的任务后,
 * 会去其他线程的等待队列里取出待执行的任务,去执行
 */
public class T11_WorkStealingPool {
    public static void main(String[] args) throws IOException {
        ExecutorService service = Executors.newWorkStealingPool();
        System.out.println(Runtime.getRuntime().availableProcessors());

        service.execute(new R(1000));
        service.execute(new R(2000));
        service.execute(new R(2000));
        service.execute(new R(2000)); //daemon
        service.execute(new R(2000));

        //由于产生的是精灵线程(守护线程、后台线程),主线程不阻塞的话,看不到输出
        System.in.read();
    }

    static class R implements Runnable {

        int time;

        R(int t) {
            this.time = t;
        }

        @Override
        public void run() {

            try {
                TimeUnit.MILLISECONDS.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(time + " " + Thread.currentThread().getName());

        }

    }
}
  • 输出结果

    8
    1000 ForkJoinPool-1-worker-1
    2000 ForkJoinPool-1-worker-3
    2000 ForkJoinPool-1-worker-5
    2000 ForkJoinPool-1-worker-4
    2000 ForkJoinPool-1-worker-2

6. ForkJoinPool

把大任务切分成一个个小任务来执行


/**
 * 把大任务切分成一个个小任务来执行
 */
public class T12_ForkJoinPool {
    static int[] nums = new int[1000000];
    //设置最小任务片为5万个数
    static final int MAX_NUM = 50000;
    static Random r = new Random();

    static {
        for (int i = 0; i < nums.length; i++) {
            nums[i] = r.nextInt(100);
        }

        System.out.println("使用Arrays.stream计算的和: " + Arrays.stream(nums).sum()); //stream api
    }


    /**
     * 没有返回值的ForkJoin
     */
    static class AddTask extends RecursiveAction {

        int start, end;

        AddTask(int s, int e) {
            start = s;
            end = e;
        }

        @Override
        protected void compute() {

            if (end - start <= MAX_NUM) {
                long sum = 0L;
                for (int i = start; i < end; i++) {
                    sum += nums[i];
                }
                System.out.println("from:" + start + " to:" + end + " = " + sum);
            } else {

                int middle = start + (end - start) / 2;

                AddTask subTask1 = new AddTask(start, middle);
                AddTask subTask2 = new AddTask(middle, end);
                subTask1.fork();
                subTask2.fork();
            }


        }

    }

    /**
     * 有返回值的ForkJoin
     */
    static class AddTaskReturn extends RecursiveTask<Long> {

        private static final long serialVersionUID = 1L;
        int start, end;

        AddTaskReturn(int s, int e) {
            start = s;
            end = e;
        }

        @Override
        protected Long compute() {

            if (end - start <= MAX_NUM) {
                long sum = 0L;
                for (int i = start; i < end; i++) {
                    sum += nums[i];
                }
                return sum;
            }

            //取中间数
            int middle = start + (end - start) / 2;

            AddTaskReturn subTask1 = new AddTaskReturn(start, middle);
            AddTaskReturn subTask2 = new AddTaskReturn(middle, end);
            subTask1.fork();
            subTask2.fork();

            return subTask1.join() + subTask2.join();
        }

    }

    public static void main(String[] args) throws IOException {
        //没有返回值
//		ForkJoinPool fjp = new ForkJoinPool();
//		AddTask task = new AddTask(0, nums.length);
//		fjp.execute(task);
//        System.in.read();

        //有返回值
        ForkJoinPool fjp = new ForkJoinPool();
        AddTaskReturn task = new AddTaskReturn(0, nums.length);
        fjp.execute(task);
        long result = task.join();
        System.out.println("使用ForkJoinPool计算出的和: "+ result);
		System.in.read();

    }
}

没有返回值的输出结果

使用Arrays.stream计算的和: 49544455

from:968750 to:1000000 = 1548248
from:218750 to:250000 = 1539443
from:718750 to:750000 = 1547722
from:468750 to:500000 = 1545115
from:843750 to:875000 = 1544120
from:937500 to:968750 = 1546731
from:187500 to:218750 = 1535385
from:437500 to:468750 = 1551864
from:687500 to:718750 = 1547479
from:812500 to:843750 = 1542819
from:406250 to:437500 = 1548120
from:593750 to:625000 = 1547728
from:656250 to:687500 = 1544024
from:156250 to:187500 = 1544398
from:93750 to:125000 = 1558824
from:375000 to:406250 = 1551525
from:906250 to:937500 = 1544222
from:625000 to:656250 = 1555051
from:562500 to:593750 = 1547992
from:875000 to:906250 = 1548874
from:31250 to:62500 = 1541202
from:343750 to:375000 = 1541366
from:62500 to:93750 = 1550987
from:281250 to:312500 = 1539370
from:312500 to:343750 = 1542633
from:250000 to:281250 = 1538104
from:125000 to:156250 = 1543367
from:0 to:31250 = 1543700
from:500000 to:531250 = 1548381
from:750000 to:781250 = 1540401
from:531250 to:562500 = 1546152
from:781250 to:812500 = 1548994

有返回值

使用Arrays.stream计算的和: 49544455
使用ForkJoinPool计算出的和: 49544455

并行流处理API

ParallelStreamAPI


/**
 * 并行流处理, 底层采用ForkJoinPool实现
 */
public class ParallelStreamAPI {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        Random r = new Random();
        for (int i = 0; i < 10000; i++) {
            nums.add(1000000 + r.nextInt(1000000));
        }
        //System.out.println(nums);

        long start = System.currentTimeMillis();
        nums.forEach(v -> isPrime(v));
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        //使用parallel stream api

        start = System.currentTimeMillis();
        nums.parallelStream().forEach(T13_ParallelStreamAPI::isPrime);
        end = System.currentTimeMillis();

        System.out.println(end - start);
    }

    /**
     * 判断是不是质数
     * @param num
     * @return
     */
    static boolean isPrime(int num) {
        for (int i = 2; i <= num / 2; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }
}

三、自定义线程池(建议)

阿里开发规范建议自定义线程池

1. ThreadPoolExecutor

/**
 * 线程池的一些参数配置和介绍
 */
public class ThreadPoolTest {


    static class Task implements Runnable {
        private int i;

        public Task(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " Task " + i);
            try {
                //模拟业务处理过程,业务执行完才会释放
                // 这里阻塞住执行到这里的线程, 等待手动释放
                System.in.read();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public String toString() {
            return "Task{" +
                    "i=" + i +
                    '}';
        }
    }

    public static void main(String[] args) {
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4,
                60, TimeUnit.SECONDS,//存活60秒内没有工作做,则将线程归还给操作系统
                new ArrayBlockingQueue<Runnable>(4),//等待队列, 里面设置只能装4个任务
                Executors.defaultThreadFactory(),//创建线程的线程工厂
                new ThreadPoolExecutor.CallerRunsPolicy()); //当线程池中没有空闲线程,并且线程的等待队列也都满了之后, 提供的拒绝策略
//                new ThreadPoolExecutor.AbortPolicy());
//                new ThreadPoolExecutor.DiscardPolicy());
//                new ThreadPoolExecutor.DiscardOldestPolicy()); //扔掉那个排队时间最久的
        //jdk默认提供了四种拒绝策略, 也可以自定义
        //这四种分别如下:
        //1.AbortPolicy: 抛异常
        //2.DiscardPolicy:扔掉, 不抛异常
        //3.DiscardOldestPolicy: 扔掉排队时间最久的
        //4.CallerRunsPolicy: 调用者处理任务: 哪个线程发起的任务, 哪个线程去处理它

        for (int i = 0; i < 8; i++) {
            tpe.execute(new Task(i));
        }

        //输出等待队列, 由于设置的最大线程数为4个, 所以第一次执行完毕后,
        //等待队里里会有8-4=4个线程
        System.out.println("第一次等待队列: " + tpe.getQueue());

        //再次执行一条任务
        tpe.execute(new Task(100));

        //再次输出
        System.out.println("第二次等待队列: " + tpe.getQueue());
        tpe.shutdown();
    }
}
  • 输出结果

    pool-1-thread-2 Task 1
    pool-1-thread-4 Task 7
    pool-1-thread-3 Task 6
    pool-1-thread-1 Task 0
    第一次等待队列: [Task{i=2}, Task{i=3}, Task{i=4}, Task{i=5}]
    main Task 100
    1
    pool-1-thread-2 Task 2
    第二次等待队列: [Task{i=3}, Task{i=4}, Task{i=5}]
    1
    pool-1-thread-1 Task 3
    pool-1-thread-3 Task 4
    1
    pool-1-thread-4 Task 5
    1
    1

YOLOv8-Pose 姿态识别 RK3588 实战:从模型训练到 RKNN 部署,精度与推理速度双提升 本教程从YOLOv8-pose模型的姿态识别训练,到RK3588的边缘量化部署,为你打造了一套“高精度+高实时性+低成本”的人体姿态分析解决方案。无论是健身动作纠正、智能安防行为检测,还是工业人员姿态监控,这套技术都能直接复用——你只需替换数据集与业务逻辑,即可快速落地专属的边缘AI姿态识别系统。如果你在实践中遇到任何卡点,欢迎随时交流。记住,人体姿态识别的价值在于“关键点准、推理快、部署易”,而这三者的平衡,正是你通过本教程能掌握的核心能力。 阅读详情

相关推荐

数据质量管理的一些思考

背景 在近期的项目当中,我们为客户落地实施了数据资产平台。随后,在数据平台中接入了客户子公司的一个业务系统的明细数据。客户希望在我们的数据平台上通过数据探索和数据分析,来挖掘一些业务价值和业务创新点。 当我们拿到数据开始进行一些初步探索的时候,发现导入平台的数据质量存在一定的问题:例如一些用于数据分析的关键字段的值为空、一些本应该有主从关系的数据对应不上、数据分类混乱等。这些问题直接影响到了对...

IDEAL Garden 1万+

解决spring cloud报ThreadPoolExecutor [Running, pool size = 10, active threads = 10, queued tasks = 0 错误

这个是我这边在生产环境碰到的问题,因为测试环境访问量不是很大,所以就没测出来。也没有压测,如果压测的话也可以轻易的压测出来这个问题,其实它具体的异常如下: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@7ed27b0 rejected from java.util.co...

星辰海的专栏 1万+

在thinkBook16的win11基础上安装ubuntu22.04

背景:联想ThinkBook16 pro 32G/512G,系统盘已安装Win11,加装一条M.2-2T固态,想在2T上分一个300GB的EXT4分区,然后把ubuntu22.04安装在该分区上,并实现Win11+Linux多系统共存。 目标:实现多磁盘下分区管理的简化,优化掉一些不必要的多余的维护性质的分区。

QzmAIoT 4001

线程池 Executor框架 自定义线程池

newFixedThreadPool)方法,该方法返回-一个固定数量的线程池,该方法的线程数始终不变,当有一个任务提交时,若线程池中空闲,则立即执行,若没有,则会被暂缓在一个任务队列中等待有空闲的线程去执行。时,若有新的任务需要执行,如果线程池实际线程数小于corePoolSize,则优先创建线程,若天于corePoolSize,则会将任务加入队列,若队列已满,则。newSingleThreadExecutor()方法,创建-一个线程的线程池,若空闲则执行,若没有空闲线程则暂缓在任务列队中。

qq_41273137的博客 784

基于STM32智能教室灯光照明人数监测系统

本文设计了一套基于STM32和物联网技术的智能教室照明系统,通过光照传感器和双红外对管实现精准人数统计,结合"光照+人数"双条件判断实现按需照明。系统采用"感知-决策-执行-云联"架构,包含环境感知、人数统计、控制执行等模块,支持本地自动控制和手机APP远程管理。测试表明系统能有效避免"长明灯"现象,具有节能降耗、管理智能化的特点。创新点在于双向人数统计算法和双条件控制逻辑,为智慧校园建设提供了实用解决方案。

1158

单片机控制双向可控硅的5种实用触发电路设计(附完整电路图)

本文深入解析了单片机控制双向可控硅的5种实用触发电路设计,涵盖从基础隔离到复杂负载驱动的实战方案。重点探讨了光电耦合器选型、过零检测同步、RC吸收电路精密计算以及应对感性负载和高噪声环境的加固策略,并提供了完整的电路图与调试避坑指南,旨在帮助开发者实现安全可靠的交流负载控制。

joy55的博客 2194

高并发线程池(三、创建线程池)

不要通过Executors类来创建线程池,一定要通过new ThreadPoolExecutor(…)来创建线程池。(参照阿里JAVA开发规范1.5泰山版) 先来介绍创建线程池涉及到的7个参数。 public ThreadPoolExecutor(int corePoolSize, //核心线程数 int maximumPoolSize, //最大线程数 long keepAliv

weixin_41758046的博客 514

FPGA实战 —— 基于UART的多设备串口通信系统设计

本文深入探讨了基于FPGA的多设备UART串口通信系统设计。针对工业控制与物联网应用中一对多通信的需求,文章对比了共享总线式、多路独立式等硬件连接方案,并详细阐述了可配置UART IP核、波特率自适应算法以及多路数据仲裁与分发逻辑等核心设计要点。最后,通过一个四传感器采集节点的实战案例,展示了从硬件连接到Verilog代码实现的完整系统构建过程。

weixin_29172963的博客 232

常用线程池介绍

线程池简介 1.线程池概念: 线程池是首先创建一个线程,它们的集合成为线程池。使用线程池可以很好的提升性能,线程池在启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行线程完成后,该线程不会死亡,而是返回线程池中成为空闲状态,等待执行下一个任务。 2.线程池的工作机制 2.1在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。 2.2一个线程同时只能执行一个任

NewBie_xW的博客 1055

破译丰田BEAN总线之谜

我对CAN的深入了解并不是从CAN本身开始的,而是起源于丰田公司自主研发的BEAN总线。由于BEAN总线协议并不是公开的,而是一种技术机密,所以当丰田车不在使用BEAN总线两年多后的今天,虽然这里还不敢公开技术细节,但回想起当年的作品,随便写写也算对自己的努力有所交代。   南方都市报惠州版曾经报道过一则新闻,说的是丰田皇冠车被盗率非常高。其实两年前就已经知道了皇冠车的防盗系数很低,所以当时的首

粤嵌 5262

开源遥感语义分割工具箱mmsegmentation基于Lovedata数据集训练模型

开源遥感语义分割工具箱mmsegmentation基于Lovedata数据集训练模型

yilvyangguang520的博客 498

线程池的5种使用方式

池化思想,不同线程池的创建方式以及差别,线程数设置的经验

a141210104的专栏 6137

华为od 面试八股文_Python_02_含答案

华为od 面试八股文_Python_02_含答案

MISAYAONE的博客 4529

SpringBoot 中如何使用通过线程池使用多线程

SpringBoot对java的线程池进行了封装, 可以通过配置直接使用线程池。 配置线程池 @Configuration @EnableAsync public class WebContextConfiguration { @Bean public Executor threadPoolTaskExecutor() { ThreadPoolTaskExe...

iuie_sl的博客 1010

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

QT-多线程、线程池的使用

在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑,如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验,还可以提升程序的执行效率。

R_conqueror的博客 1737

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java多线程——线程池使用

本文介绍一下Java多线程中线程池的使用方式。

qq_50867577的博客 1270

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

JAVA 多线程实现、线程池创建使用、多线程的异步操作

进程是:一个应用程序(1个进程是一个软件)。线程是:一个进程中的执行场景/执行单元。注意:一个进程可以启动多个线程。java主线程: 每个java程序都含有一个线程,那就是主线程(main线程)。Java应用程序都是从主类main方法执行的,当jvm加载代码,发现卖弄方法之后,就会启动一个线程,这个线程就是主线程,负责执行main方法。如果在主线程里面创建其他线程,就会在主线程和其他线程来回切换,直到其他所有线程结束才会结束主线程。

weixin_74412978的博客 1125

多线程-线程池的使用

当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。线程对象在不同的时期有不同的状态。那么 Java 中的线程存在哪几种状态呢?Java 中的线程/* 新建 */NEW ,/* 可运行状态 */RUNNABLE ,/* 阻塞状态 */BLOCKED ,/* 无限等待状态 */WAITING ,/* 计时等待 *//* 终止 */TERMINATED;// 获取当前线程的状态。

2302_81141145的博客 1057

Spring Boot 多线程池统一配置与使用教程

推荐实践建议说明拆分多线程池根据业务类型独立配置,防止互相干扰统一构建器避免重复代码异常封装器所有任务包装为,防止吞异常监控工具开发/线上查看线程使用情况若使用@Async,必须开启。

weixin_47766420的博客 808

java多线程及线程池使用

Java多线程及线程池的使用Java多线程一、Java多线程涉及的包和类二、Java创建多线程的方式三、Java线程池1. 创建线程池ThreadPoolExecutor的7个参数2. 线程池的执行流程3. 线程池的使用示例1)用java原生的线程池类 ThreadPoolExecutor2)用Spring推出的线程池工具 ThreadPoolTaskExecutor4. 获取多线程的运行结果—使用CompletableFuture1)CompletableFuture概述2)CompletableFutu

NA_imu的博客 879

Python中多线程和线程池的使用方法

上述代码中,我们定义了一个process函数,它接受一个列表作为参数,对列表中的每个元素进行运算,并将结果保存到另一个列表中。在上面的代码中,我们首先定义了一个GetHtmlThread类,继承自threading.Thread类,然后在类的构造函数中传入需要爬取的URL。在主程序中,我们创建了5个线程,每个线程都执行task函数,并传入不同的参数。但是,这种单线程爬取的方式效率较低,因为在获取HTML代码的时候需要等待响应,而在等待响应的过程中CPU会空闲,无法充分利用计算机的性能。

weixin_47831992的博客 4817

多线程之线程池使用

多线程的线程池使用常用实现多线程的方式为什么要用线程池JUCExecutorsExecutorThreadPoolExecutorThreadPoolExecutor的原理ThreadPoolExecutor参数的设置选择线程池的优常用的线程池ThreadPoolExecutor的参数解释如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰

i_computer的博客 651

JAVA多线程——线程池的使用

JAVA多线程——线程池 问题:经常创建和销毁使用量特别大的资源时,比如并发情况下的线程,对性能影响很大。 解决:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建和销毁、实现重复利用。 好处: 提高响应速度(减少了创建新线程的时间) 减低资源消耗(重复利用线程池中的线程) 便于线程管理 可以设置线程池的属性 corePoolSize:核心池的大小 maximumPoolSize: 最大线程数 keepAliveTime:线程没有任务时最多保持多久时间后会终止

万里顾一程的博客 562

java多线程编程 线程池的使用

Java中的多线程编程是现代软件开发中不可或缺的一部分,尤其是在处理高性能计算、并发请求和异步任务时。线程池是Java多线程编程中的一个重要概念,它可以显著提高程序的性能和响应速度。下面我们详细探讨线程池的基本原理、如何在Java中使用线程池以及一些最佳实践。

yuehua00的专栏 1020

多线程-线程池配置及使用

 在开发过程中,如高并发场景、批量处理任务、记录日志等场景。多线程降低资源消耗,避免频繁线程创建/销毁的开销。提高响应速度。可限制并发线程数(如核心/最大线程数配置),防止资源耗尽导致系统崩溃。

qq_36833673的博客 416

java使用多种方式实现多线程及线程池的使用

java实现多线的N种方式

gengjiangtaoBlog 3989
上一篇: 多线程---并发容器的使用
下一篇: Mysql调优总结
意田天
博客等级 码龄7年 41粉丝 89原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

意田天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值