JUC线程池

article/2025/10/12 7:02:40

一、JUC介绍

java.util.concurrent包(简称:JUC)。JUC主要是让开发者在多线程编程中更加简单、方便一些。 通过JDK内置了一些类、接口、关键字,补充完善了JDK对于并发编程支持的“短板”。

主要功能:(1)Executor:线程池(2)Atomic:原子操作类(3)Lock:锁(4)Tools:信号量工具类(4)并发集合:提供了线程安全的集合类。

二、线程池

(1)什么是线程池:

内存中的一块空间。这块空间里面存放一些已经实例化好的线程对象。当代码中需要使用线程时直接从线程池获取。当代码中线程执行结束或需要销毁时,把线程重新放入回到线程池,而不是让线程处于死亡状态。

(2)线程池的优缺点:

优点:(1)降低系统资源消耗。通过重用线程对象,降低因为新建和销毁线程产生的系统消耗。(2)提高系统响应速度。直接从内存中获取线程对象,比新建线程更快。(3)提供线程可管理性。通过对线程池中线程数量的限制,避免无限创建线程导致的内存溢出或CPU资源耗尽等问题。

缺点:默认情况下,无论是否需要使用线程对象,线程池中都有一些线程对象,也就是说会占用一定内存。

三、JUC中的线程池

1. Executor介绍:

Executor 线程池顶级接口, 接口中只有一个execute()方法,方法参数为Runnable类型。

2.ThreadPoolExecutor

是JUC中提供的默认线程池实现类, Executor的子类。

构造方法中的七个参数:

(1)int  corePoolSize核心线程数:创建线程池后,默认线程池中并没有任何的线程,执行了从线程池获取线程执行任务的时候才会创建核心线程完成任务的执行。 如果没有达到指定corePoolSize, 即使有空闲的核心线程, 也会创建新的核心线程执行任务, 直到达到了corePoolSize。 达到corePoolSize后, 从线程池获取线程执行任务, 有空闲的核心线程, 空闲的线程会执行新任务。

(2)BlockingQueue<Runnable>  workQueue阻塞队列:

理解:阻塞:当队列为空时,阻塞获取任务;当队列放满时,阻塞添加任务。

  1. 当线程池中的线程数目达到指定的corePoolSize后,并且所有的核心线程都在使用中, 再来获取线程执行任务, 会将任务添加到缓存任务的阻塞队列中,也就是workQueue。

  2. 队列可以设置queueCapacity 参数,表示任务队列最多能存储多少个任务。

(3)int  maximumPoolSize最大线程数:

  1. 所有的核心线程都被使用中,且任务队列已满时,线程池会创建新的线程执行任务,直到线程池中的线程数量达到maximumPoolSize。

  2. 被使用的线程数等于maximumPoolSize ,且任务队列已满,则已超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。

(4)long  keepAliveTime线程最大空闲时间:

  1. 线程池中存在空闲的线程, 就会处于空闲(alive)状态, 只要超过keepAliveTime, 空闲的线程就会被销毁,直到线程池中的线程数等于corePoolSize。

  2. 如果设置了allowCoreThreadTimeOut=true(默认false),核心线程也可以被销毁。

(5)TimeUnit  unitkeepAliveTime 时间单位:

TimeUnit是枚举类型。

public enum TimeUnit {//纳秒NANOSECONDS(TimeUnit.NANO_SCALE),//微妙MICROSECONDS(TimeUnit.MICRO_SCALE),//毫秒MILLISECONDS(TimeUnit.MILLI_SCALE),//秒SECONDS(TimeUnit.SECOND_SCALE),//分钟MINUTES(TimeUnit.MINUTE_SCALE),//小时HOURS(TimeUnit.HOUR_SCALE),//天DAYS(TimeUnit.DAY_SCALE);private static final long NANO_SCALE   = 1L;private static final long MICRO_SCALE  = 1000L * NANO_SCALE;private static final long MILLI_SCALE  = 1000L * MICRO_SCALE;private static final long SECOND_SCALE = 1000L * MILLI_SCALE;private static final long MINUTE_SCALE = 60L * SECOND_SCALE;private static final long HOUR_SCALE   = 60L * MINUTE_SCALE;private static final long DAY_SCALE    = 24L * HOUR_SCALE;
}

(6)ThreadFactory  threadFactory线程工厂:创建线程对象。

(7)RejectedExecutionHandler  handler线程池拒绝策略:

只有当任务队列已满,且线程数量已经达到maximunPoolSize才会触发拒绝策略。

  1. AbortPolicy: 丢弃新任务,抛出异常,提示线程池已满(默认)。

  2. DisCardPolicy: 丢弃任务,不抛出异常。

  3. DisCardOldSetPolicy: 将消息队列中最先进入队列的任务替换为当前新进来的任务。

  4. CallerRunsPolicy: 由调用该任务的线程处理, 线程池不参与, 只要线程池未关闭,该任务一直在调用者线程中。

package com.java.test;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*
* 使用实例
* */public class Test01 {public static void main(String[] args) {ThreadPoolExecutor te = new ThreadPoolExecutor(2,4,5, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(5));te.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}});te.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}});te.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}});}
}

3.Executors

(1)介绍:Executors时线程池的工具类,返回值都是ExecutorService接口的实现类, 底层大多是调用ThreadPoolExecutor()。

(2)newThreadPoolExecutor()方法:单线程

//源码public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}

效果总结:

  1. 它只会创建一条工作线程处理任务;

  2. 采用的阻塞队列为LinkedBlockingQueue, 它是一个无界队列, 底层为链表。

package com.java.test;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
* 使用方式
* */
public class Test02 {public static void main(String[] args) throws InterruptedException {ExecutorService es = Executors.newSingleThreadExecutor();while (true) {es.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());// while (true){}}});Thread.sleep(1000);}}
}

(3)newFixedThreadPool(int nThreads)方法:自定义线程数

//源码public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}

效果总结:

  1. 它是一种固定大小的线程池;

  2. corePoolSize和maximunPoolSize都为用户设定的线程数量nThreads;

  3. keepAliveTime为0,意味着一旦有多余的空闲线程,就会被立即停止掉;但这里keepAliveTime无效;

  4. 阻塞队列采用了LinkedBlockingQueue,它是一个无界队列, 底层为链表;

  5. 由于阻塞队列是一个无界队列,因此永远不可能拒绝任务;

  6. 由于采用了无界队列,实际线程数量将永远维持在nThreads,因此maximumPoolSize和keepAliveTime将无效。

package com.java.test;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TestnewFixedThreadPool {public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(5);while (true){executorService.submit(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}});Thread.sleep(1000);}}
}

(4)newCachedThreadPool():缓存线程池

//源码public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
}

效果总结:

  1. 它是一个可以无限扩大的线程池;

  2. 它比较适合处理执行时间比较小的任务;

  3. corePoolSize为0,maximumPoolSize为无限大,意味着线程数量可以无限大;

  4. keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死;

  5. 采用SynchronousQueue(同步队列)装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程。

package com.java.test;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TestnewCachedThreadPool {public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newCachedThreadPool();while (true){executorService.submit(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());while (true){}}});Thread.sleep(1000);}}
}

(5) newScheduledThreadPool():

//源码public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);
}public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE,DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,new DelayedWorkQueue());
}

效果总结:

  1. 它采用DelayQueue存储等待的任务

  2. 它会根据time的先后时间排序,若time相同则根据sequenceNumber排序;

  3. DelayQueue也是一个无界队列;

  4. 工作线程会从DelayQueue取已经到期的任务去执行;

  5. 执行后也可以将任务重新定时, 放入队列中;

  6. 支持定时, 周期性执行。

package com.java.test;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class TestnewScheduledThreadPool {public static void main(String[] args) {ScheduledExecutorService ses = Executors.newScheduledThreadPool(5);//定时执行: 3秒后执行一次/* ses.schedule(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}}, 3, TimeUnit.SECONDS);*///周期执行: 参数1: 延时时间  参数2: 周期性执行, 隔多少时间执行一次ses.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}}, 0, 3, TimeUnit.SECONDS);}
}

(6)newWorkStealingPool():工作窃取池

工作原理(工作窃取算法):把一个Thread 分叉(fork)成多个子线程。让多个子线程执行本来一个线程应该执行的任务。最后把多个线程执行结果合并。

如果在分叉后一个线程执行完成,另外的线程还没有结束,会从双端队列中尾部处理任务,另一个线程从头部取任务,防止出现线程竞争。


http://chatgpt.dhexx.cn/article/8g1sWAiS.shtml

相关文章

JUC

&#xff08;尚硅谷笔记&#xff09; Java JUC 简介  在 Java 5.0 提供了 java.util.concurrent &#xff08;简称 JUC &#xff09;包&#xff0c;在此包中增加了在并发编程中很常用 的实用工具类&#xff0c;用于定义类似于线程的自定义子 系统&#xff0c;包括线程池、异…

JUC基础知识(个人总结)

声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识 内容详细全面, 言辞官方的文章 2. 由于是个人总结, 所以用最精简的话语来写文章 3. 若有错误不当之处, 请指出 一. 前置基础: IO 操作不占用 cpu, 只是我们一般拷贝文件使用的是【…

1、JUC概述

1.1 什么是JUC 在Java中&#xff0c;线程部分是一个重点&#xff0c;本篇文章说的JUC 也是关于线程的。JUC就是java.util .concurrent工具包的简称。这是一个处理线程的工具包&#xff0c;JDK1.5开始出现的。 1.2 线程和进程的概念 进程和线程 进程&#xff08;Process&…

JUC基础【万字篇】

JUC 1、什么是JUC JUC&#xff1a;指的是java.util三个并发编程工具包 java.util.concurrentjava.util.concurrent.atomicjava.util.concurrent.locks 实现多线程的四种方式&#xff1a; 继承Thread类实现Runnable接口实现Callable接口线程池 业务&#xff1a;普通的线程代…

java--JUC快速入门(彻底搞懂JUC)

java–JUC快速入门&#xff08;彻底搞懂JUC&#xff09; 文章目录 java--JUC快速入门&#xff08;彻底搞懂JUC&#xff09;1、学习多线程之前需要知道的一些概念。2、JUC的结构3、Lock锁(重点)4、集合类不安全5、Callable()6、常用的辅助类7、读写锁8、阻塞队列9、线程池 1、学…

Dbeaver做数据迁移

1、选择源头数据库的表、鼠标右击、选择导出数据 2、在数据转化弹框中&#xff0c;双击 ‘数据库&#xff0c;数据表’ 那一栏 3、选择目标数据库&#xff0c;调整字段类型映射关系 4、调整字段的映射关系 目前遇到的字段类型&#xff0c;只有 int&#xff0c;bigint 转 num…

dbeaver工具连接达梦数据库

、一 概述 DBeaver 是一个基于 Java 开发&#xff0c;免费开源的通用数据库管理和开发&#xff0c;DBeaver 采用 Eclipse 框架开发&#xff0c;支持插件扩展&#xff0c;并且提供了许多数据库管理工具&#xff1a;ER 图、数据导入/导出、数据库比较、模拟数据生成等&#xff0…

DBeaver 格式化sql

有时候我们拿到了一条sql语句是长长的&#xff0c;非常不容易阅读&#xff0c;这时我们就想说哪里可以格式下sql代码。 方法有很多种&#xff0c;这里我就用Dbeaver来格式化sql。 ①打开Dbeaver ②复制sql代码到SQL编辑器中&#xff0c;并选中 ③按ctrlshiftF&#xff0c;即…

【DBeaver】常用自定义设置

文章目录 背景一、用户界面设置1.1、22.3.4版本1.1.1、SQL编辑器-字体设置1.1.2、查询结果-字体设置 1.2、23.0.0版本1.2.1、应用字体&#xff08;导航栏等&#xff09;1.2.2、文本字体&#xff08;SQL输出、文本编辑器等&#xff09; 二、常规设置2.1、连接类型设置/环境设置 …

DBeaver导入Excel数据

目录 前言 导入准备 ​导入步骤 1.选中数据库表&#xff0c;右键&#xff0c;然后点击导入数据 2.双击CSV,选择待导入的文件 3.修改编码格式&#xff08;可选&#xff0c;不乱码不用&#xff09; 4.点击下一步&#xff0c;修改列的类型 5.一直下一步&#xff0c;点击…

Dbeaver基本使用

1&#xff1a;与plsql相比&#xff0c;Dbeaver没有右击直接查看表注释的功能&#xff0c;但是Dbeaver提供了一个“打开声明”的功能&#xff0c;里面可以查看一些比较实用的内容&#xff1a;表列注释、创建该表的create语句&#xff1a; 2&#xff1a;在一般开发的情况下&#…

【大数据】Hive可视化工具dbeaver

Hive可视化工具dbeaver 1、dbeaver基本介绍 dbeaver是一个图形化的界面工具&#xff0c;专门用于与各种数据库的集成&#xff0c;通过dbeaver我们可以与各种数据库进行集成通过图形化界面的方式来操作我们的数据库与数据库表&#xff0c;类似于我们的sqlyog或者navicat。 2、…

DBeaver安装及使用手册

一、DBeaver安装 1、在[DBeaver官网](https://dbeaver.io/download)进行数据库工具下载&#xff0c;下载好后双击运行2、选择语言后&#xff0c;点击OK 3、点击下一步 4、接受许可 5、选择可使用者&#xff0c;然后点击下一步 6、选择组件&#xff0c;一般选择默认即可 7…

DBeaver-Driver-All ( DBeaver驱动包,所有JDBC驱动整合包)

DBeaver-Driver-All DBeaver-Driver-All ( DBeaver驱动包 )整合所有DBeaver的JDBC驱动包&#xff0c;供DBeaver使用&#xff0c;无需每次都搜索和下载&#xff0c;只需clone本项目即可&#xff0c;一个包包含几乎所有的驱动&#xff0c;如果有缺漏的驱动欢迎提Issue补充。 DBe…

DBeaver 下载安装

1 下载地址(我下载的 Windows版本&#xff0c;根据系统需要选择版本) Releases dbeaver/dbeaver GitHubFree universal database tool and SQL client. Contribute to dbeaver/dbeaver development by creating an account on GitHub.https://github.com/dbeaver/dbeaver/rel…

DBeaver 安装

DBeaver 目录 DBeaver1、介绍2、发展史3、版本介绍4、下载与安装5、DBeaver 连接数据库&#xff08;MySql&#xff09;6、DBeaver 连接数据库&#xff08;Hive&#xff09;7、DBeaver 功能简介 1、介绍 DBeaver是一种通用数据库管理工具&#xff0c;适用于需要以专业方式使用数…

DBeaver驱动安装

最近打算用DBeaver它来查看SQLite文件&#xff0c;需要安装驱动&#xff0c;总是安装不上有点苦恼 下载驱动的时候可能会出现如下提示&#xff1a; Can’t create driver instance Error creating driver ‘SQLite’ instance. Most likely required jar files are missing. …

使用 DBeaver 导入数据

如何上传数据 在开始使用 DBeaver 之前&#xff0c;用户 以 excel 格式收集了有关电视剧的信息。他的文件已经包含所有必要的列&#xff0c;但我们的英雄不想将其中一些列传输到数据库&#xff0c;因为它们是为他个人使用而创建的&#xff0c;与站点访问者无关。要仅快速加载网…

Dbeaver配置迁移

换电脑了,希望Dbeaver中的连接也一起带过去 但在Dbeaver中找了一圈,没找到可以导出配置的功能 搜了一圈资料并自己尝试,发现配置文件保存在两个文件中,只要把老电脑的这两个文件换到新电脑中就能迁移数据库连接配置

DBeaver 超级详细的安装与使用

一、下载DBeaver DBeaver是一种通用数据库管理工具&#xff0c;适用于需要以专业方式使用数据的每个人&#xff1b;适用于开发人员&#xff0c;数据库管理员&#xff0c;分析师和所有需要使用数据库的人员的免费(DBeaver Community) 的多平台数据库工具。 DBeaver支持80多个数据…