并发编程之线程池的详细解析

线程池

线程池的优势: 线程池做的工作只要是控制运行的线程数量,处理过程中将任务放入队列,然后线程创建石后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。

它的主要特点为:线程复用;控制最大并发数;管理线程。

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

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

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

线程池类的结构:

Executors 线程池工具类,用来创建线程池实例化

固定大小的线程池 FixedThreadPool

运行结果:

可以看到,线程池中的三个线程轮流执行任务。

代码:

复制代码
java 复制代码
public class ThreadPool {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);//创建固定大小的线程池
        try {
            for (int i = 0; i < 5; i++) {
                executorService.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"--开始任务");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }
​
    }
}
​

动态扩容的线程池 CachedThreadPool

运行结果:

模拟各个线程排队过来执行任务,线程池只需要开辟一个线程就正好可以一个一个执行任务

代码:

复制代码
java 复制代码
public class ThreadPool {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();//创建动态大小的线程池
        try {
            for (int i = 0; i < 5; i++) {
                try {
                    TimeUnit.SECONDS.sleep(1);  //模拟各个线程排队过来执行任务
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                executorService.execute(()->{
​
                    System.out.println(Thread.currentThread().getName()+"--开始任务");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }
​
    }
}
​

运行结果:

模拟各个线程同时过来执行任务,线程池同时创建五个线程来执行任务

代码:

java 复制代码
public class ThreadPool {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();//创建固定大小的线程池
        try {
            for (int i = 0; i < 5; i++) {
                executorService.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"--开始任务");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }
​
    }
}
​
相关推荐
ambition202426 分钟前
操作系统同步:读者-写者问题与读写公平法详解(附每个 PV 操作含义)
linux·开发语言·数据结构·unix
chuan.bai3 小时前
Java RAG 实战(第 11 篇):RAG 知识工作台网页
java·开发语言·人工智能
离陌在学C#5 小时前
C# 事件(Event)详解:从概念到实战
开发语言·c#
0x535 小时前
网站通信(一)
java
To_OC6 小时前
Next.js + Redis 构建笔记系统:Redis Hash 实战与性能优化
redis·后端·next.js
Terra.K6 小时前
Java异常学习[特殊字符]
java·开发语言·学习
葡萄城技术团队7 小时前
InfluxDB 2\.x 深度解析:核心架构、Flux 函数与制造业落地指南(三)
java·开发语言·架构
Super 含7 小时前
Android 启动优化(五):线程、GC 与 IO 为什么会拖慢启动?
java·服务器·数据库
counting money7 小时前
Java IO流详解:从InputStream到文件操作实战
java·开发语言·python
wuyk5558 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法