当前位置: 首页 > news >正文

微服务 第一章 Java线程池技术应用

系列文章目录

第一章 Java线程池技术应用

在这里插入图片描述


文章目录

  • 系列文章目录
    • @[TOC](文章目录)
  • 前言
  • 1、Java创建线程方式回顾
    • 1.1、继承Thread类(只运行一次)
      • 1.1.1、改造成主线程常驻,每秒开启新线程运行
      • 1.1.2、匿名内部类
      • 1.1.3、缺点
      • 1.1.4、扩展知识:Java内部类
        • 1.1.4.1、静态内部类
        • 1.1.4.2、匿名内部类
    • 1.2、实现Runnable接口
      • 1.2.1、普通类实现Runnable接口
      • 1.2.2、匿名方式创建Runnable实现类
      • 1.2.3、使用Lambda方式创建匿名Runnable类
      • 1.2.4、缺点
      • 1.2.5、扩展Lambda表达式
    • 1.3、实现Callable接口
      • 1.3.1、普通类实现Callable接口
  • 2、线程池
    • 2.1、五种创建线程的方式
    • 2.2、new ThreadPoolExecutor()创建线程
      • 2.2.1、拒绝策略

前言

介绍Java的线程、线程池等操作

1、Java创建线程方式回顾

1.1、继承Thread类(只运行一次)

public class ThreadTest extends Thread{@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}public static void main(String[] args) {new ThreadTest().start();}
}

1.1.1、改造成主线程常驻,每秒开启新线程运行


import java.util.Date;@Slf4j
public class ThreadTest extends  Thread{@Overridepublic void run() {log.info("线程名称:{} , 当前时间:{}" , Thread.currentThread().getName() , new Date().getTime() );}public static void main(String[] args) {while (true) {try {new ThreadTest().start();Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("主线程常驻");}}}

1.1.2、匿名内部类

import lombok.extern.slf4j.Slf4j;@Slf4j
public class ThreadTest extends  Thread{public static void main(String[] args) {Thread thread = new Thread() {@Overridepublic void run() {log.info("Hello {}" , "world");}};thread.start();}}

1.1.3、缺点

继承了Thread类之后,就不能继承其他类

1.1.4、扩展知识:Java内部类

成员内部类(外部类内部使用,外部类外部使用)


import lombok.extern.slf4j.Slf4j;@Slf4j
public class Outer {public static void main(String[] args) {Inner inner = new Outer().initTest();log.info(inner.innerTest());}public Inner initTest(){Inner inner = new Inner();return  inner;}class Inner{public Inner(){}public Inner(String s){}public String innerTest(){return "Inner Hello world";}}
}

1.1.4.1、静态内部类

import lombok.extern.slf4j.Slf4j;@Slf4j
public class Outer {public static void main(String[] args) {Inner inner = new Inner();log.info(inner.innerTest());}public void initTest(){Inner inner = new Inner();}static class Inner{public Inner(){}public Inner(String s){}public String innerTest(){return "Inner Hello world";}}
}

1.1.4.2、匿名内部类

import lombok.extern.slf4j.Slf4j;@Slf4j
public class Outer {public static void main(String[] args) {Outer outer = new Outer();outer.sayHello();}public void sayHello(){IMessage iMessage = new IMessage() {//匿名类@Overridepublic String sayHello() {return "Hello world";}};log.info(iMessage.sayHello());}interface IMessage{String sayHello();}}

1.2、实现Runnable接口

1.2.1、普通类实现Runnable接口

import lombok.extern.slf4j.Slf4j;@Slf4j
public class StatSales implements Runnable{@Overridepublic void run() {log.info("统计销量");}public static void main(String[] args) {Thread thread = new Thread() {@Overridepublic void run() {log.info("Hello world");}};thread.start();}
}

1.2.2、匿名方式创建Runnable实现类

public static void main(String[] args) {Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("统计成绩");}};new Thread(runnable).start();}

1.2.3、使用Lambda方式创建匿名Runnable类

// 使用 Lambda 匿名 Runnable 方式
Thread t3 = new Thread(() -> {
//添加业务方法…
});
// 启动线程
t3.start();

public static void main(String[] args) {Thread thread = new Thread(() -> {System.out.println("统计平均寿命");});thread.start();
}

1.2.4、缺点

不能获得程序的执行结果

1.2.5、扩展Lambda表达式

把函数作为一个方法的参数
表达式语法:

(parameters) -> expression

(parameters) ->{ statements; }

说明:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
  • 举例:

    // 1. 不需要参数,返回值为 5  
    () -> 5  // 2. 接收一个参数(数字类型),返回其2倍的值  
    x -> 2 * x  // 3. 接受2个参数(数字),并返回他们的差值  
    (x, y) -> x – y  // 4. 接收2个int型整数,返回他们的和  
    (int x, int y) -> x + y  // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
    (String s) -> System.out.print(s)
    

    1.3、实现Callable接口

    FutureTask+Callable

    1.3.1、普通类实现Callable接口

    public class StatScore implements Callable<Double> {@Overridepublic Double call() throws Exception {//统计分数的逻辑return 88.98;}
    }
    
     public static void main(String[] args) throws ExecutionException, InterruptedException {StatScore statScore = new StatScore();//跟FutureTask 关联上FutureTask<Double> doubleFutureTask = new FutureTask<>(statScore);//跟Thread关联上Thread thread = new Thread(doubleFutureTask);thread.start();log.info(String.valueOf(doubleFutureTask.get()));}
    

    2、线程池

    线程池就是存放线程的池子,池子里存放了很多可以复用的线程。
    使用线程池的优势

  • 提高效率,创建好一定数量的线程放在池中,等需要使用的时候就从池中拿一个,这要比需要的时候创建一个线程对象要快的多。
  • 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
  • 提升系统响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线程用的时间为T3,那么使用线程池就免去了T1和T3的时间;
  • 在这里插入图片描述

    2.1、五种创建线程的方式

    //创建一个单线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    //创建一个定长的线程池,可控制最大并发数,超出的线程进行队列等待。 ExecutorService executorService =
    Executors.newFixedThreadPool(2); //可以创建定长的、支持定时任务,周期任务执行。
    ExecutorService executorService = Executors.newScheduledThreadPool(2);
    //创建一个可以缓存的线程池,如果线程池长度超过处理需要,可以灵活回收空闲线程,没回收的话就新建线程 ExecutorService
    executorService = Executors.newCachedThreadPool(); //创建一个具有抢占式操作的线程池
    ExecutorService executorService = Executors.newWorkStealingPool();

    2.2、new ThreadPoolExecutor()创建线程

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

    参数说明:

    参数含义解释
    corePoolSize该线程池中核心线程数最大值核心线程生命周期无限,即使空闲也不会死亡
    maximumPoolSize线程总数最大值任务队列满了以后当有新任务进来则会增加一个线程来处理新任务(线程总数<maximumPoolSize )
    keepAliveTime闲置超时时间当线程数大于核心线程数时,超过keepAliveTime时间将会回收非核心线程
    unitkeepAliveTime 的单位
    workQueue线程池中的任务队列*
    threadFactory为线程池提供创建新线程的线程工厂*
    RejectedExecutionHandler饱和策略抛出异常专用,当队列和最大线程池都满了之后的饱和策略。

    在这里插入图片描述

    2.2.1、拒绝策略

    ThreadPoolExecutor的饱和策略可以通过调用setRejectedExecutionHandler来修改。JDK提供了几种不同的RejectedExecutionHandler实现,每种实现都包含有不同的饱和策略:AbortPolicy、CallerRunsPolicy、DiscardPolicy和DiscardOldestPolicy。

    拒绝策略如下:

  • CallerRunsPolicy : 调用线程处理任务
  • AbortPolicy : 抛出异常
  • DiscardPolicy : 直接丢弃
  • DiscardOldestPolicy : 丢弃队列中最老的任务,执行新任务
  •         RejectedExecutionHandler rejected = null;//默认策略,阻塞队列满,则丢任务、抛出异常rejected = new ThreadPoolExecutor.AbortPolicy();//阻塞队列满,则丢任务,不抛异常rejected = new ThreadPoolExecutor.DiscardPolicy();//删除队列中最旧的任务(最早进入队列的任务),尝试重新提交新的任务rejected = new ThreadPoolExecutor.DiscardOldestPolicy();//队列满,不丢任务,不抛异常,若添加到线程池失败,那么主线程会自己去执行该任务rejected = new ThreadPoolExecutor.CallerRunsPolicy();

    总结: 就是被拒绝的任务,直接在主线程中运行,不再进入线程池。

相关文章:

微服务 第一章 Java线程池技术应用

系列文章目录 第一章 Java线程池技术应用 文章目录 系列文章目录[TOC](文章目录) 前言1、Java创建线程方式回顾1.1、继承Thread类(只运行一次)1.1.1、改造成主线程常驻&#xff0c;每秒开启新线程运行1.1.2、匿名内部类1.1.3、缺点1.1.4、扩展知识&#xff1a;Java内部类1.1.4…...

行业追踪,2023-09-14

自动复盘 2023-09-14 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…...

传输层协议--UDP

引入 传输层负责数据能够从发送端传输到接收端。 端口号&#xff08;Port&#xff09; 端口号标识了一个主机上进行通信的一个进程。 两个问题&#xff1a; 1. 一个进程可以绑定多个端口号吗&#xff1f;--可以 2.一个端口号可以绑定多个进程吗&#xff1f;--不可以 我们…...

微信会员卡开发流程

功能需求&#xff1a; 通过微信第三方平台创建的模板小程序&#xff0c;想要实现用户在小程序支付一定金额后领取会员卡&#xff0c;领取会员卡后可给用户下发一定数量的优惠券&#xff0c;并且实现用户在小程序消费享受商品折扣。 开发流程&#xff1a; 一、了解微信的3个平…...

《算法竞赛·快冲300题》每日一题:“点灯游戏”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 点…...

常见高级语言的输入与输出训练(一)

文章目录 题目概述1 输入描述: 输出描述: 输入 输出 示例C语言代码 题目概述2 题目描述 输入描述: 输出描述: 输入 输出 示例Java代码 前言 本文主要讲解两个算法题的代码实现 题目概述1 计算ab 打开以下链接可以查看正确的代码 数据范围&#xff1a;数据组数满…...

恭喜!龙蜥获得 2023 大学生操作系统设计赛二等奖及特殊贡献奖

经过多月的激烈角逐&#xff0c;2023 全国大学生系统能力大赛操作系统设计赛&#xff08;以下简称“2023 大学生操作系统赛”&#xff09; 圆满结束。经过 2023 大学生操作系统赛评审组和技术委员会的复核&#xff0c;面向全国公布了此次大赛的获奖名单。龙蜥社区不负众望&…...

中项系统集成项目管理2023上半年真题及解析

中项系统集成项目管理2023上半年真题及解析 上午题1. 在 (1) 领域&#xff0c;我国还远未达到世界先进水平&#xff0c;需要发挥新型举国体制优势&#xff0c;集中政府和市场两方面的力量全力发展2. ChatGPT于 2022年 11 月 30 日发布&#xff0c;它是人工智能驱动的 (2) 工具3…...

实时显示当前文件夹下的文件大小,shell脚本实现

图片来源于网络&#xff0c;如果侵权请联系博主删除&#xff01; 需求&#xff1a; 写一个shell终端命令&#xff0c;实时显示当前文件夹下的文件大小 实现&#xff1a; 您可以使用以下的Shell脚本命令来实时显示当前文件夹下的文件大小&#xff1a; while true; docleardu …...

7、Spring之依赖注入源码解析(下)

resolveDependency()实现 该方法表示,传入一个依赖描述(DependencyDescriptor),该方法会根据该依赖描述从BeanFactory中找出对应的唯一的一个Bean对象。 @Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Null…...

图片码二次渲染绕过

目录 一、环境 1、代码 2、文件处理方式 3、图片码的制作 二、绕过图片重构 1、可行性分析 2、数据比对 3、完成绕过 一、环境 以upload-labs靶场第十七关为例 1、代码 源码为&#xff1a; <?php include ../config.php; include ../head.php; include ../menu.…...

点评项目核心内容

目录 拦截器设置 集群的session共享问题 基于redis实现共享session登录 创建bean对象技巧 什么是缓存 使用缓存来处理对象 使用String类型缓存来处理集合 缓存更新策略 主动更新策略 缓存穿透 空串""和null的区别 缓存null值解决穿透问题 缓存雪崩 缓存击穿…...

海外商城小程序为什么这么受欢迎?

随着全球化的进程海外商城小程序在近年来获得了广泛的关注和使用。海外商城小程序是一种基于互联网技术的应用程序&#xff0c;为用户提供了便捷的购物体验和跨境交易服务。本文将深入探讨海外商城小程序的受欢迎原因&#xff0c;从多个维度进行分析就其未来发展进行思考&#…...

Linux Day13 ---信号量

一、信号量 1.1 一些概念 用来管理对资源的访问 一个特殊的变量&#xff0c;只允许对它进行等待(wait)和发送信号(signal),代表可用资源个数&#xff0c; 取0,1 二值信号量 取 3,5 计数信号量 p操作&#xff1a;原子减一&#xff0c;代表获取资源&#xff0c;可能阻塞 v…...

《动手学深度学习 Pytorch版》 4.10 实战Kaggle比赛:预测比赛

4.10.1 下载和缓存数据集 import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)): #save"""下载一个…...

jQuery补充

文章目录 简介安装语法选择器元素选择器#id 选择器.class 选择器事件常用事件方法 效果显示隐藏淡入淡出滑动动画停止动画获取内容和属性添加元素删除元素操作css父辈 &#x1f49b;&#x1f49b;孔子云&#xff1a;温故而知新&#xff0c;可以为师矣&#x1f49b;&#x1f49b…...

goaccess 日志分析 nginx

分析命令&#xff1a; goaccess -a -d -f /mnt/winshare/access-2023070112.log -p goaccess.conf -o /mydata/nginx/html/2023070112_new.html分析日志时的参数 goaccess使用参数详解-a 开启 UserAgent 列表。开启后会降低解析速度 -c 在程序开始运行时显示 日志/日期 配…...

认养一头牛———众筹+合伙人商业模式解析

2016年成立以来&#xff0c;认养一头牛致力于打造数字化乳业第一品牌&#xff0c;只为一杯好牛奶。公司在创立三年内完成了10个亿销售目标&#xff0c;被业界称为新消费品牌黑马&#xff0c;一举闯入互联网新消费梯队的视线。未来三年&#xff0c;认养一头牛将着力打造全国最大…...

前端面试的话术集锦第 11 篇:高频考点(React和Vue两大框架)

这是记录前端面试的话术集锦第十一篇博文——高频考点(React和Vue两大框架),我会不断更新该博文。❗❗❗ React 和Vue应该是国内当下最火热的前端框架。当然,Angular也是一个不错的框架,但是这个产品,国内使用的人很少,因而,框架的章节中不会涉及到Angular的内容。 这…...

前端js下载zip文件异常问题解决

目录 一&#xff0c;本文解决问题如下 二&#xff0c;原下载代码 1&#xff0c;ajax get 下载文件 2&#xff0c;下载异常图&#xff1a; 三&#xff0c;成功下载的 1&#xff0c; JQuery 实现文件下载xhr 2&#xff0c;图例 引言&#xff1a; 本人使用的ajax 下载&…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...