大家好,我是Leo!今天准备和大家一起分享的知识是线程池,刚好今天在看八股文,就顺带写一下并把一些实践的例子和大家分享一下…

线程池是什么?

线程池,简单的说就是一个管理线程的池子。

可以帮助管理线程,当我们需要使用线程时,我们可以直接从池子中获取即可,可以降低资源的消耗,因为采用池化技术可以重复利用已建立的线程,可以降低线程创建和销毁造成的损耗。而且可以提高响应速度,当任务到达时,从池子中拿线程,肯定是比你重新创建一条线程快的。

线程池的主要参数

其实在阿里巴巴Java开发手册中是不希望我们采用Executors来创建线程池,更推荐采用ThreadPoolExecutor来创建线程池,因为这样线程池的资源配置由程序员自己决定,可以降低爆内存的风险,ThreadPoolExecutor支持7大参数,分别如下。

  • int corePoolSize:核心线程数

  • int maximumPoolSize:最大线程数

  • long keepAliveTime:非核心线程存活时间

  • TimeUnit unit:非核心线程存活时间单位

  • BlockingQueue workQueue:等待队列

  • ThreadFactory threadFactory:创建线程使用工厂

  • RejectedExecutionHandler handler:线程池拒绝策略

线程池的拒绝策略

线程池常见的有4中拒绝策略:

  • AbortPolicy:直接抛出异常RejectedExecutionException,是默认的处理方法

  • CallerRunsPolicy:由调用线程来处理这个任务

  • DiscardOldestPolicy:丢弃队列最前面的任务,然后尝试执行该任务

  • DiscardPolicy:直接丢弃当前任务

当然除了上述策略,也支持自定义拒绝策略,通过实现RejectedExecutionHandler,重写

rejectedExecution方法既可以自定义拒绝策略。

public class RejectHandler implements RejectedExecutionHandler {

    @Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 自定义拒绝策略
System.out.println("我是自定义拒绝策略~"); }
}

创建线程池的方式

Executors.newCachedThreadPool(),创建一个缓存线程池,内部也是调用了ThreadPoolExecutor,但是它的最大任务数量是Integer.MAX_VALUE,maximumPoolSize也就失效了,在设置了等待200ms时,也可以发现,一直都是一个线程在处理,即可以体现是按需进行创建。

private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

    public void test() {
for (int i = 0; i < 100; i++) {
int index = i;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.submit(new Thread(() -> System.out.println(Thread.currentThread().getName() + ":" + index)));
}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-18fWKUMX-1677772046315)(C:\Users\DY\AppData\Roaming\marktext\images\2023-03-02-17-36-53-image.png)]

Executors.newSingleThreadExecutor(),这个是创建一个核心线程数为1,最大线程数也为1的线程池,可以看到只有一条线程在处理。

private static ExecutorService singeThreadPool = Executors.newSingleThreadExecutor();
public void testSingle() {
for (int i = 0; i < 10; i++) {
int index = i; singeThreadPool.submit(new Thread(() -> System.out.println(Thread.currentThread().getName() + ":" + index)));
}
}

Executors.newFixedThreadPool(), 可以指定核心线程数和最大线程数,没有所谓的非空闲时间。

private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
public void testFixed() {
for (int i = 0; i < 100; i++) {
int index = i;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
fixedThreadPool.submit(new Thread(() -> System.out.println(Thread.currentThread().getName() + ":" + index)));
}
}

Executors.newScheduledThreadPool(Runnable command, long delay, TimeUnit uni)

支持延时任务的提交

除此之外,还有一个newSingleThreadScheduledExecutor可以创建支持延时的单线程线程池。

private static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
public void testScheduled() {
for (int i = 0; i < 1; i++) {
int index = i;
System.out.println("添加时间" + new Date());
scheduledThreadPool.schedule(new Thread(() ->{
System.out.println(Thread.currentThread().getName() + ":" + index + "time:" + new Date());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}), 1, TimeUnit.SECONDS);
}
}

关闭线程池

  • shutdown(),关闭线程池,会处理已提交的任务,不会再添加任务

  • shutdownNow(),不会处理已提交任务,也不会再添加新的任务

本文主要介绍了线程池常见的创建方式、7个参数、线程池的拒绝策略以及自定义实现拒绝策略,希望本文内容对你有帮助!!!

Java常见的线程池的创建及使用的更多相关文章

  1. Java线程池的创建详解

    本篇文章主要总结了Java创建线程池的三种方式以及线程池参数的详细说明,对线程池感兴趣的同学可以作为参考学习. 1)通过工具类java.util.concurrent.Executors的静态方法来创 ...

  2. JAVA线程池的创建与使用

    为什么要用线程池? 我们都知道,每一次创建一个线程,JVM后面的工作包括:为线程建立虚拟机栈.本地方法栈.程序计数器的内存空间(下图可看出),所以线程过多容易导致内存空间溢出.同时,当频繁的创建和销毁 ...

  3. Android 四种常见的线程池

    引入线程池的好处 1)提升性能.创建和消耗对象费时费CPU资源 2)防止内存过度消耗.控制活动线程的数量,防止并发线程过多. 我们来看一下线程池的简单的构造 public ThreadPoolExec ...

  4. java并发之线程池的使用

    背景 当系统并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要消耗大量的系统资源. 所以需要一个办法使得线程可以 ...

  5. java并发包&线程池原理分析&锁的深度化

          java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的, ...

  6. Java常用四大线程池用法以及ThreadPoolExecutor详解

    为什么用线程池? 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处-理效率 2.线程并发数量过多,抢占系统资源从而导致阻塞 3.对线程进行一些简单的管理 在Java中,线 ...

  7. Java多线程_线程池

    作用我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为 ...

  8. Java中的线程池用过吧?来说说你是怎么理解线程池吧?

    前言 Java中的线程池用过吧?来说说你是怎么使用线程池的?这句话在面试过程中遇到过好几次了.我甚至这次标题都想写成[Java八股文之线程池],但是有点太俗套了.虽然,线程池是一个已经被说烂的知识点了 ...

  9. Java同步之线程池详解

    带着问题阅读 1.什么是池化,池化能带来什么好处 2.如何设计一个资源池 3.Java的线程池如何使用,Java提供了哪些内置线程池 4.线程池使用有哪些注意事项 池化技术 池化思想介绍 池化思想是将 ...

  10. Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...

随机推荐

  1. mysql知识点一

    1.mysql中造成索引失效的原因有哪些?如何分析和解决? 原因: 1.like以通配符%开头索引失效 通常用的索引数据结构是B+树,而索引是有序排列的 优化:一种是使用覆盖索引,另一种是把%放后面 ...

  2. Glinux 1395 build ENV setup

    1.安装ubuntu 14.04.05 LTS 64bit 2.初始化root 密码 sudo passwd  Password: <--- 输入安装时那个用户的密码  Enter new UN ...

  3. redis为什么是单核单线程

    1)以前一直有个误区,以为:高性能服务器 一定是多线程来实现的 原因很简单因为误区二导致的:多线程 一定比 单线程 效率高,其实不然! 在说这个事前希望大家都能对 CPU . 内存 . 硬盘的速度都有 ...

  4. JSON常见用法

    https://blog.csdn.net/weixin_43631296/article/details/105253434

  5. day1 第一个程序“Hello world!”

    程序运行机制 源程序(.java文件)->java编译器->字节码(.class文件)->类装载器->字节码校验器->解释器->操作系统平台Java源码后缀名:.j ...

  6. Nginx如何升级Openssl

    1. 什么是Openssl? 在计算机网络上,OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连线者的身份.这个包广泛被应用在互联网的网页服务器 ...

  7. 内存取证 volatility的使用

    volatility 简介: volatility(挖楼推了推) 是一个开源的框架,能够对导出的内存镜像进行分析,能够通过获取内核的数据结构,使用插件获取内存的详细情况和运行状态,同时可以直接dump ...

  8. flutter系列之:创建一个内嵌的navigation

    目录 简介 搭建主Navigator 构建子路由 总结 简介 我们在flutter中可以使用Navigator.push或者Navigator.pushNamed方法来向Navigator中添加不同的 ...

  9. fastposter v2.13.0 一分钟完成开发海报 [云服务来袭]

    fastposter v2.13.0 一分钟完成开发海报 [云服务来袭] fastposter海报生成器是一款快速开发海报的工具.只需上传一张背景图,在对应的位置放上组件(文字.图片.二维.头像)即可 ...

  10. 自己动手从零写桌面操作系统GrapeOS系列教程——17.用汇编语言清空屏幕

    学习操作系统原理最好的方法是自己写一个简单的操作系统. 在QEMU中会默认输出一些字符,有时候会干扰我们自己输出的字符.一个比较好的办法是向将屏幕清空,再输出我们想要输出的字符.下面就来学习如何清空屏 ...