多线程:线程池

线程池

认识线程池

什么是线程池

  • 线程池就是一个可以复用线程的技术

不使用线程池的问题

  • 用户每发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能。

如何创建线程池 

谁代表线程池

  • JDK5.0起提供了代表线程池的接口:ExecutorService。

如何得到线程池对象 

  • 方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个现线程池对象。

  • 方式二:使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象。

ThreadPoolExecutor构造器

  •  参数一:corePoolSize:指定线程池的核心线程的数量
  • 参数二:maximumPoolSize:指定线程池的最大线程数量
  • 参数三:keepAliveTime:指定临时线程的存货时间
  • 参数四:unit:指定临时线程存货的时间单位(秒、分、时、天)
  • 参数五:workQueue:指定线程池的任务队列
  • 参数六:threadFactory:指定线程池的线程工厂
  • 参数七:handler:指定现场尺寸的任务拒绝策略(线程都在忙,任务队列也满了的时候,新任务来了该怎么处理)

线程池的注意事项

  • 临时线程什么时候创建?

                新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程

  • 什么时候会开始拒绝新任务?

                核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务

线程池处理Runnable任务

ExecutorService的常用方法

方法名称说明
void execute(Runnable command)执行Runnable任务
Future<T> submit(Callable<T> task)执行Callable任务,返回未来任务对象,用于获取线程返回的结果
void shutdown()等全部任务执行完毕后,再关闭线程池

List<Runnable> shutdownNow()

立即关闭线程池,停止正在执行的任务,并返回队列中未执行的任务

ThreadPoolTest1类

import java.util.concurrent.*;public class ThreadPoolTest1 {public static void main(String[] args) {// 通过ThreadPoolExecutor创建一个线程池对象ExecutorService pool = new ThreadPoolExecutor(3,5,8,TimeUnit.SECONDS, new ArrayBlockingQueue<>(4),                    Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());Runnable target = new MyRunnable();pool.execute(target); //线程会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //线程会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //线程会自动创建一个新线程,自动处理这个任务,自动执行的pool.execute(target); //复用前面的核心线程pool.execute(target); //复用前面的核心线程pool.shutdown(); //等着线程池的任务全部执行完毕后,再关闭线程//pool.shutdownNow(); //立即关闭线程池,不管任务是否执行完毕}
}

MyRunnable类

public class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}
}

新任务拒绝策略

策略详解
ThreadPoolExecutor.AbortPolicy丢弃任务并抛出RejectedExecutionException异常。是默认的策略
ThreadPoolExecutor.DiscardPolicy丢弃任务,但是不抛出异常,这是不推荐的做法
ThreadPoolExecutor.DiscardOldestPolicy抛弃队列中等待最久的任务,然后把当前任务加入队列中
ThreadPoolExecutor.CallerRunsPolicy由主线负责调用任务的run()方法从而绕过线程池直接执行

线程池处理Callable任务

ExecutorService的常用方法

方法名称说明
void execute(Runnable command)执行任务/命令,没有返回值,一般用来执行Runnable任务
Future<T> submit(Callable<T> task)执行任务,返回未来任务对象获取线程结果,一般拿来执行Callable任务
void shutdown()等待执行完毕后关闭线程池
List<Runnable> shutdownNow()立即关闭,停止正在执行的任务,并返回队列中未执行的任务

ThreadPoolTest2类

import java.util.concurrent.*;public class ThreadTest2 {public static void main(String[] args) throws Exception {// 通过ThreadPollExecutor创建一个线程池对象ExecutorService pool = new ThreadPoolExecutor(3,5,8,TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());// 使用线程处理Callable任务Future<String> f1 = pool.submit(new MyCallable(100));Future<String> f2 = pool.submit(new MyCallable(200));Future<String> f3 = pool.submit(new MyCallable(300));Future<String> f4 = pool.submit(new MyCallable(400));System.out.println(f1.get());System.out.println(f2.get());System.out.println(f3.get());System.out.println(f4.get());}
}

MyCallable类

import java.util.concurrent.Callable;public class MyCallable implements Callable<String> {private int n;public MyCallable(int n) {this.n = n;}// 重写call方法@Overridepublic String call() throws Exception {// 描述线程的任务,返回线程执行返回后的结果// 需求:求1~n的和返回int sum = 0;for (int i = 1; i < n; i++) {sum += i;}return Thread.currentThread().getName() + "求出了1~" + n + "的和是:" + sum;}
}

Executors工具类事项线程池

Executors

  • 是一个线程池的工具类,提供了很多静态方法用于返回不同特点的线程池对象。
方法名称说明
public static ExecutorService newFixedThreadPoll(int nThreads)创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程池会补充一个新的线程替代它
public static ExecutorService newSingleThreadExecutor()创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程
public static ExecutorService newCachedThreadPoll()线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了60s则会被回收掉
public static ScheduledExecutorService newScheduledThreadPoll(int nThreads)创建一个线程池,可以实现在给定的延迟后允许任务,或者定期执行任务

 注意:这些方法的底层,都是通过线程池的实现类ThreadPoolExecutor创建的线程池对象。

Executors使用可能存在的陷阱

  • 大型并发系统环境中使用Executors如果不注意可能会出现系统风险。

其他线程知识:并发、并行、线程的生命周期

进程

  • 正在运行的程序(软件)就是一个独立的进程。
  • 线程是属于进程的,一个进程中可以同时运行很多个线程。
  • 进程中的多个线程其实是并发和并行执行的。

并发的含义

  • 进程中的线程是由CPU负责调度执行的,但CPU能同时处理线程的数量有限,为了保证全部线程都能往前执行,CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,这就是并发。

并行的理解

  • 在同一时刻上,同时有多个线程在被CPU调度执行。

线程的生命周期

  • 也就是线程从生到死的过程中,经历的各种状态及状态转换。
  • 理解线程这些状态有利于提升并发编程的理解能力。
Java线程的状态
  • Java总共定义了6种状态
  • 6种状态都定义在Thread类的内部枚举类中。

 线程的6种状态互相转换

 线程的6种状态总结
线程状态说明
NEW(新建)线程刚被创建,但是并未启动
Runnable(可运行)线程已经调用了start(),等待CPU调度
Blocked(锁阻塞)线程在执行的时候未竞争到锁对象,则该线程进入Blocked状态
Waiting(无限等待)一个线程进入Waiting状态,另一个线程调用notify或者notifyAll方法才能够唤醒
Timed Waiting(计时等待)同waiting状态,有几个方法(sleep,wait)有超时参数,调用他们将进入Timed Waiting状态
Teminated(被终止)因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/518835.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蜻蜓FM语音下载(mediadown)

一、介绍 蜻蜓FM语音下载&#xff08;mediadown&#xff09;&#xff0c;能够帮助你下载蜻蜓FM音频节目。如果你是蜻蜓FM会员&#xff0c;它还能帮你下载会员节目。 二、下载地址 本站下载&#xff1a;蜻蜓FM语音下载&#xff08;mediadown&#xff09; 百度网盘下载&#…

爬虫入门到精通_框架篇15(Scrapy框架安装)

1 Scrapy安装 Scrapy的安装有多种方式&#xff0c;它支持Python2.7版本及以上或Python3.3版本及以上。下面说明Python3环境下的安装。 Scrapy依赖的库比较多&#xff0c;至少需要依赖库有Twisted14.0,lxml 3.4,pyOpenSSL 0.14。而在不同平台环境又各不相同&#xff0c;所以在安…

【Flutter 面试题】dart是值传递还是引用传递?

【Flutter 面试题】dart是值传递还是引用传递&#xff1f; 文章目录 写在前面解答补充说明值传递示例引用传递示例总结 写在前面 关于我 &#xff0c;小雨青年 &#x1f449; CSDN博客专家&#xff0c;GitChat专栏作者&#xff0c;阿里云社区专家博主&#xff0c;51CTO专家博主…

视频编码中常用的测试YUV系列及说明

vcc最新规定的测试序列如下所示&#xff0c;对于RA和LD配置&#xff0c;所有序列的所有帧都需要测试&#xff0c;对于intra配置仅需测试前8帧。 每列含义如下&#xff1a; A1、A2测试序列在LD配置下编码时应编码帧数为帧率的三倍。 “M”表示在该配置下必须测试这条序列。 …

算法沉淀——动态规划之其它背包问题与卡特兰数(leetcode真题剖析)

算法沉淀——动态规划之其它背包问题与卡特兰数 二维费用的背包问题01.一和零02.盈利计划 似包非包组合总和 Ⅳ 卡特兰数不同的二叉搜索树 二维费用的背包问题 01.一和零 题目链接&#xff1a;https://leetcode.cn/problems/ones-and-zeroes/ 给你一个二进制字符串数组 strs…

登录校验-过滤器-拦截器

会话技术 会话&#xff1a;用户打开浏览器&#xff0c;访问Wb服务器的资源&#xff0c;会话建立&#xff0c;直到有一方断开连接&#xff0c;会话结束。在一次会话中可以包含多次请求和响应。 会话跟踪&#xff1a;一种维护浏览器状态的方法&#xff0c;服务器需要识别多次请求…

【MySQL知识体系】第2章 数据库与表的创建(一)

第2章 数据库与表的创建 2.1 数据库操作 2.2 表操作 文章目录 第2章 数据库与表的创建2.1 数据库操作2.1.1 创建第一个数据库2.1.2 更新数据库名称&#xff08;数据库创建后无法修改名称&#xff09;2.1.3 删除数据库2.1.4 取个合适的数据库名称 第2章 数据库与表的创建 2.1 数…

抖音商家短视频直播流量变现运营SOP地图

【干货资料持续更新&#xff0c;以防走丢】 抖音商家短视频直播流量变现运营SOP地图 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 抖音运营资料合集&#xff08;完整资料包含以下内容&#xff09; 目录 【提升短视频运营效率的专业指南】 高效运营&#xf…

浅谈Linux进程隐藏

浅谈Linux进程隐藏 文章目录 浅谈Linux进程隐藏前言环境变量的绕过常用的命令在哪里环境变量的调用前置知识的了解Netstat伪装怎么去甄别 LD_PRELOAD简单实例check.c重载函数设置LD_PERLOAD删除环境变量LD_PERLOAD PS的隐藏readdir函数如何HOOK编译并验证 LD_PRELOAD的其他利用…

运算符重载(Operator Overloading)

定义 在C中&#xff0c;运算符重载&#xff08;Operator Overloading&#xff09;是一种允许程序员为自定义数据类型重新定义或重载已有的运算符的功能。通过运算符重载&#xff0c;我们可以使得自定义类型的对象能够像内置类型&#xff08;如int、float等&#xff09;一样使用…

基于yolov5的柿子成熟度检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的柿子成熟度检测系统&#xff0c;系统既能够实现图像检测&#xff0c;也可以进行视屏和摄像实时检测_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的柿子成熟度检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的…

AES加密学习

AES&#xff08;高级加密标准&#xff09;是一种对称密钥加密算法&#xff0c;用于加密和解密数据。它被广泛应用于各种安全领域&#xff0c;包括但不限于网络通信、数据存储和软件保护。 历史背景 AES是由比利时密码学家Joan Daemen和Vincent Rijmen设计的Rijndael算法演变而…