代码编织梦想

一 、我们为什么需要使用线程池?

总体来说,线程池有如下的优势:

(1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

(2)提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。

(3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

二、线程池应用场景介绍

1:网购商品秒杀

2:云盘文件上传和下载

3:12306网上购票系统等

总之

只要有并发的地方、任务数量大或小、每个任务执行时间长或短的都可以使用线程池;

只不过在使用线程池的时候,注意一下设置合理的线程池大小即可;(

三、Java线程池的实现方式

  • newCachedThreadPool、

  • newFixedThreadPool、

  • newSingleThreadExecutor、

  • newScheduleThreadPool。

3.1 newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理所需,可灵活回收空闲线程,若线程数不够,则新建线程。

  public void testCache(){
        // 创建一个缓存线程池对象
        ExecutorService cacheThreadPool = Executors.newCachedThreadPool();

        // 通过 for 循环并发多个操作
        for (int i = 0; i < 10; i++){
            final int index = i;
            // 线程的使用  execute 执行
            cacheThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Log.d("TAG",Thread.currentThread().getName()+" "+index);
                }
            });
        }
    }

运行结果

4a0e190abdee9b6b053085721979483d.png

在线程池2中最高有6个线程在并发

测试线程池长度超过处理所需,可灵活回收空闲线程

实验用例中只有一个线程

  public void testCache(){
        // 创建一个缓存线程池对象
        ExecutorService cacheThreadPool = Executors.newCachedThreadPool();

        // 通过 for 循环并发多个操作
        for (int i = 0; i < 10; i++){
            final int index = i;

            try {                  // 一个任务工作完休息,就不会有多个进程并发
                Thread.sleep(2*1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 线程的使用  execute 执行
            cacheThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Log.d("TAG",Thread.currentThread().getName()+" "+index);
                }
            });
        }
    }

3.2 newFixedThreadPool

创建一个固定大小的线程池。可控制并发的线程数量,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。

public void testFixed(){  // 这种线程池控制的是最大并发数
        // 创建一个缓存线程池对象 但需要告诉他最大并发线程数
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 10; i++){
            final int index = i;

            // 线程的使用  execute 执行
            fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Log.d("TAG",Thread.currentThread().getName()+" "+index);
                }
            });

        }
    }

运行结果

1cb4d10010b3d7b768aee5980548fc5e.png

3.3 newSingleThreadExecutor

创建一个单线程的线程池,即只创建唯一的工作者线程来执行任务,,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

 public void testSingle(){
        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
        for (int i = 0; i< 10; i++){
            final int index = i;
            singleThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Log.d("TAG",Thread.currentThread().getName()+" "+ index);
                }
            });
        }
    }

运行结果

28ac3f21bd242d2d098666c71d103943.png

3.4 newScheduleThreadPool

创建一个定长的线程池,支持定时及周期性任务执行。

  1. 定时任务 // 定时3秒以后执行

  1. 周期任务 // 定时2秒以后执行,每个3秒执行一次

    public void testSchedule(){
        ExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
//        // 定时3秒以后执行
//        ((ScheduledExecutorService) scheduledExecutorService).schedule(new Runnable() {
//            @Override
//            public void run() {
//                Log.d("TAG","delay 3 second");
//            }
//        },3, TimeUnit.SECONDS);

        // 定时2秒以后执行,每个3秒执行一次
        ((ScheduledExecutorService) scheduledExecutorService).scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Log.d("TAG","delay 2 second,and execute every 3 second");
            }
        },2,3,TimeUnit.SECONDS);
        scheduledExecutorService.shutdown();
    }
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/x1998fly/article/details/129601062

多线程 -- 使用线程池时如何接收另外一个线程池中执行代码的返回值_都说名字长不会被发现的博客-爱代码爱编程

前言:最近在处理实际业务时遇到一个问题,订单表中有50-100万数据需要生成订单流水。应用部署在了四台服务器上,如何在竞争到锁的服务器上处理订单生成订单流水的速度更快,考虑使用一个线程池去负责读取数据,一个线程池负责去插入数

多线程--线程池的正确打开方式-爱代码爱编程

概述 线程可认为是操作系统可调度的最小的程序执行序列,一般作为进程的组成部分,同一进程中多个线程可共享该进程的资源(如内存等)。JVM线程跟内核轻量级进程有一对一的映射关系,所以JVM中的线程是很宝贵的。 一般在工程上多线程的实现是基于线程池的。因为相比自己创建线程,多线程具有以下优点 线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作

多线程-常见四种类型线程池总结-爱代码爱编程

线程池 线程池的概念: 在Java 5之后,并发编程引入了一堆新的启动、调度和管理线程的API。Executor框架便是Java5中引入的,其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作. Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行

多线程基础--线程池中线程池的个数确定-爱代码爱编程

我们在多线程开发过程中,难免会遇到线程池使用, 但是,有时候我们会发现,线程池设置的线程数量是一个棘手的问题,线程数量设置过多或者过少,都会导致系统性能无法发挥出来,那我们该如何设置线程数量? 在确定线程数量前,我们首先要思考一个问题就是系统性能优化指标,通常情况下,优化指标有降低延迟和提高吞吐量两个。 降低延迟:发送请求到接收数据的时间。 提高吞吐

一文必懂-线程与线程池-爱代码爱编程

线程与线程池 线程线程状态四种创建方式协程(非重点)线程池特点线程池架构说明创建线程池Executors.newFixedThreadPool(int)Executors.newSingleThreadPool()Executors.newCachedThreadPool()new ThreadPoolExecutor()线程池 7 大参数线程运行

Java多线程 - 线程池常用容量设置-爱代码爱编程

线程执行方式 线程的执行是由CPU进行调度的,一个CPU在 同一时刻只会执行一个线程 操作系统利用了时间片轮转的方式,CPU给每个任务都服务一定的时间,然后把当前任务的状态保存下来,再加载下一个任务的状态后,继续服务下一个任务。任务的保存及再加载的过程叫作 上下文切换 ,上下文切换会导致额外的开销 线程池容量设置参考 建议与cpu相关,如果是 不经

多线程--02--01--线程池常见面试题-爱代码爱编程

一、线程池常见面试题 1.1、线程池参数(7-4-4) 1、corePoolSize:线程池的基本大小,当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。说白了就是,即便是线程池里没有任何任务,也会有corePoolSize个线程在候着等任务。

多线程--线程和线程池的用法_傻鱼爱编程的博客-爱代码爱编程

目录 1. 线程 1.1 并发和并行 1.2 进程和线程 1.3 创建线程的方式  1.3.1 继承 Thread 的方式(无返回值) 1.3.2 实现Runnable接口(无返回值) 1.3.3 实现Callable接口(有返回值) 1.4 线程的生命周期 2. 线程池  2.1 为什么要使用线程池 2.2 使用线程池的优势 2.

java多线程与线程池-02线程池与锁-爱代码爱编程

线程池与锁 第4章 线程池入门 4.1 ThreadPoolExecutor ThreadPoolExecutor是应用最广的底层线程池类,它实现了Executor和ExecutorService接口。 4.1.1