IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java多线程的几种实现方式 -> 正文阅读

[Java知识库]Java多线程的几种实现方式


前言

Executors和ThreadPoolExecutor和ThreadPoolTaskExecutor三种来讨论


一、Executors

1.Executors.newFixedThreadPool:创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待;
2.Executors.newCachedThreadPool:创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程;
3.Executors.newSingleThreadExecutor:创建单个线程数的线程池,它可以保证先进先出的执行顺序;
4.Executors.newScheduledThreadPool:创建一个可以执行延迟任务的线程池;
5.Executors.newSingleThreadScheduledExecutor:创建一个单线程的可以执行延迟任务的线程池;
6.Executors.newWorkStealingPool:创建一个抢占式执行的线程池(任务执行顺序不确定)【JDK 1.8 添加】

重点

Executors不推荐使用:
根据阿里巴巴规范:创建的线程池需要自己把控,而Executors生成的线程池不够灵活,可能会造成资源浪费,或者请求堆积

二、ThreadPoolExecutor

手动创建的线程池
构造方法:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {}

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {}

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {}

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {}

1.corePoolSize:核心线程数,长期存在的线程数
2.maximumPoolSize:最大线程数,最大存在的线程数
3.keepAliveTime:存活时长
4.unit:时长单位
5.threadFactory:?于生成线程,?般我们可以?默认的就可以了。
6.workQueue:任务队列,用于存储线程池的待执行任务的
7.handler:拒绝策略

拒绝策略

DiscardPolicy : 忽略旧任务(队列第一个任务)
AbortPolicy : 提示异常,拒绝执行(默认的拒绝策略)
CallerRunsPolicy : 使用调用线程池的线程来执行任务
DiscardOldestPolicy :  忽略最新任务 

ThreadPoolExecutor使用方式

1.定义一个线程池

/**
* 任务线程池
*/
final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 12, 30,TimeUnit.SECONDS, new ArrayBlockingQueue(200),
    (Runnable r, ThreadPoolExecutor executor)-> new ThreadPoolExecutor.AbortPolicy());
//定义了一个核心为2,最大长度为12,存活30秒,拒绝策略为抛异常的线程池

2.定义一个任务类

class AddTask implements Runnable{

     String targetId;
     String aiFunctionId;
     String labelId;
     String templateId;
     String catalogId;

     public AddTask(String targetId,String aiFunctionId,String labelId,String templateId,String catalogId){
         this.targetId=targetId;
         this.aiFunctionId=aiFunctionId;
         this.labelId=labelId;
         this.templateId=templateId;
         this.catalogId=catalogId;
     }

     @Override
     public void run() {
        buildTask(targetId,aiFunctionId,labelId,templateId,catalogId);
     }
 }
//buildTask是具体的实现方法

3.线程池执行

threadPool.execute(new AddTask(mediaId,aiFunctionId,labelId,templateId,catalogId));

三.ThreadPoolTaskExecutor

与上两种jdk提供的不同,这种是spring提供的线程池,是对第二种线程池的封装

1.定义线程池

没有提供带参构造方法,更适合配置@Async使用

@Configuration
public class ExecturConfig {
    @Bean("taskExector")
    public Executor taskExector() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        int i = Runtime.getRuntime().availableProcessors();//获取到服务器的cpu内核
        executor.setCorePoolSize(5);//核心池大小
        executor.setMaxPoolSize(100);//最大线程数
        executor.setQueueCapacity(1000);//队列程度
        executor.setKeepAliveSeconds(1000);//线程空闲时间
        executor.setThreadNamePrefix("tsak-asyn");//线程前缀名称
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//配置拒绝策略
        return executor;
    }

使用注解异步方法

@Async("taskExector")
public void buildTask(String targetId,String aiFunctionId,String labelId,String templateId,String catalogId){
	
}

使用自带的方法,和ThreadPoolExecutor方法一样,需要定义个task实现Runnable

threadPoolTaskExecutor.execute(new Runnable);

注意

@Async可能出现失效的问题:
含有@Async或@Transational注解的bean被spring扫描时,spring会为其生成一个代理类,代理类继承原来的目标bean,如果该注解作用在方法上,则会重写目标bean对应方法,将该方法做相应的增强(如果该注解是作用在类上,则会增强该类的所有方法)。而方法a不含@Async或@Transational,所以不会增强处理,所以方法a是直接调用方法b,导致@Async或@Transational失效。

解决方法:
1.将带有注解的方法写在另外一个类中
2.使用反射获取代理类的方法:

A a = context.getBean(A.class); //从spring容器中重新获取A的代理对象,再调用b方法注解即生效
a.bMethod();
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-01 15:33:33  更:2022-05-01 15:35:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:54:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码