从零全面认识 多线程

news2024/11/19 2:39:00

目录

 1.基本概念

2.创建线程方式

2.1直接建立线程

2.2实现Runnable接口

3.3实现Callable接口

3.4 了解Future接口

Future模式主要角色及其作用

3.5实例化FutureTask类

3.实现线程安全

3.1定义

3.2不安全原因

3.3解决方案

3.4volatile与synchronized区别

3.5Lock与sychronized区别

4.极端情况——线程死锁

4.1定义

4.2解决措施

5.线程池的掌握

5.1核心参数

5.2生命周期

5.3处理流程

5.4Handler拒绝策略

5.5常见线程池

5.6线程池的使用


 1.基本概念

线程状态:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、

                  等待(Waiting)、超时等待(Timed Waiting)、终止(Terminated)

锁(同步监视器):分为悲观锁和乐观锁,常见的有偏向锁、轻量级锁、重量级锁

                                CAS(Compare And Swap)是一种乐观锁的实现方式,通过比较并

                                交换来实现并发控制

2.创建线程方式

Runnable接口、Callable接口、Future接口、FutureTask类

2.1直接建立线程

        创建Thread子类,按需求重写run()方法 【run代表此线程执行时会做的事】

        这里的属性若为 多线程共享属性,加static修饰

2.2实现Runnable接口

 这里的 多线程共享属性 可以是非静态的,因为多线程共用此接口

3.3实现Callable接口

(1)实现接口Callable,重写call()回调方法,会返回一个值,值类型由Callable泛型决定

实例化上述类,利用FutureTask(Callable)构造器实例化类

3.4 了解Future接口

异步调用的多线程开发模式之一(异步:当我们需要调用一个函数方法时,并不急着要结果。让被调者立即返回,让它在后台慢慢处理这个请求;此时则可以先处理一些其他任务

Future模式主要角色及其作用

Main->调用Client发送请求

Data->返回数据的接口

Client->返回Data对象,立即返回FutureData,并开启ClientThread线程装配RealData

FutureData->虚拟数据,伪造数据立即返回,最终装配上RealData

RealData->真实数据,构造缓慢

3.5实例化FutureTask类

FutureTask用于异步获取执行结果或取消执行任务

通过传入Runnable或者Callable的任务给FutureTask,

直接调用其run方法或者放入线程池执行,

最后在外部通过FutureTask的get方法异步获取执行结果(适合耗时操作)

3.实现线程安全

3.1定义

多线程环境下,对共享资源的访问不会导致数据出错。

因此和单线程执行相同的操作,结果相同

3.2不安全原因

1. 线程是抢占式的执行,线程间的调度充满了随机性
2. 多个线程对同一个变量进行修改操作
3. 对变量的操作不是原子性的
4. 内存可见性导致的线程安全问题
5. 指令重排序也会影响线程安全

3.3解决方案

使用同步机制(如synchronized、Lock)、

使用线程安全的数据结构(如ConcurrentHashMap)

synchronized:Java关键字,属于隐式锁,可以修饰方法或代码块

Lock:JAVA接口,显式锁

原理上都是通过对共享资源加锁来实现同步。

3.4volatile与synchronized区别

volatile轻量级的锁,保证变量的可见性和有序性,但仅仅保证单个变量的原子性

可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入,解决多核CPU缓存可见性问题

有序性:采用内存屏障来实现的,就是在编译器生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序

原子性:对单个volatile变量的读写具有原子性,对“volatile变量++”这种复合操作则不具有原子性,

而synchronized既保证可见性又保证原子性

volatile适用于单个变量的读写操作,而synchronized适用于复合操作或临界区。

3.5Lock与sychronized区别

使用方式: 1、Lock接口是显式锁,即我们需要调用其内部定义的方法显式地加锁和解锁,更加灵活,Lock对象创建Condition对象来实现线程通信

                   2、synchronized关键字是隐式锁,无需显式地获取和释放锁,使用方便

 功能特性:Lock弥补了synchronized的不足,它新增了特性:1、可中断地获取锁,2、 非阻塞地获取锁,3、可超时地获取锁

实现机制:AQS是队列同步器,是用来构建锁的基础框架,Lock实现类都是基于AQS实现的

                  synchronized的底层是采用Java对象头来存储锁信息的,对象头包含三部分,分别是Mark Word、Class Metadata Address、Array length。

4.极端情况——线程死锁

4.1定义

多个线程相互等待对方释放资源,导致无法继续执行

4.2解决措施

  1. 避免嵌套锁、

  2. 按固定的顺序获取锁、

  3. 设置超时时间、

  4. 使用Lock对象代替synchronized关键字。

5.线程池的掌握

5.1核心参数

核心线程数(corePoolSize):依据任务的处理时间和每秒产生的任务数量来确定

最大线程数(maximumPoolSize):参照核心线程数和系统每秒产生的最大任务数决定

线程空闲时间(keepAliveTime):用户自设置合理时间间隔

任务队列(workQueue):一定的顺序或优先级来执行任务

拒绝策略(handler):线程池已经关闭或达到饱和(最大线程和队列都已满)状态时,新提交的

                                任务将会被拒绝。

5.2生命周期

线程池的生命周期包含5个状态:

  • RUNNING:线程池正在运行,接受新任务并执行。
  • SHUTDOWN:任务队列不清空,线程池不再接受新任务,等待执行的任务继续执行完毕。
  • STOP:清空任务队列,不等待执行的任务,尝试终止正在执行的任务。
  • TIDYING:当线程池及任务队列为空时进入该状态,线程池会执行钩子函数(待实现)。
  • TERMINATED:线程池终止状态,所有任务执行完毕,线程池关闭。

注意:

在线程池的生命周期中,它的状态是不可逆

5.3处理流程

向线程池提交一个任务之后,线程池按照如下步骤处理这个任务

注意:

1、新建的线程处理完当前任务后,变为空闲线程,继续处理等待队列中的任务。

2、如果线程的空闲时间达到了keepAliveTime,则线程池会销毁一部分线程,将线程数量收缩至corePoolSize。

5.4Handler拒绝策略

Hanlder通常处理消息,但线程池中帮助任务异步执行,发送消息并执行UI更新等操作

拒绝策略分别对应着RejectedExecutionHandler接口的4个实现类,

1、让调用者自己执行任务

2、直接抛出异常

3、丢弃任务不做任何处理

4、删除队列中最老的任务并把当前任务加入队列

5.5常见线程池

FixedThreadPool、CachedThreadPool、ScheduledThreadPool

5.6线程池的使用

1:利用Executors工厂类的静态方法,创建线程池对象;
2:编写Runnable或Callable实现类的实例对象;
3:利用ExecutorService的submit方法或ScheduledExecutorService的schedule方法提交并执行线程任务
4:如果有执行结果,则处理异步执行结果(Future)
5:调用shutdown()方法,关闭线程池

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二百三十、MySQL——MySQL表的索引

1 目的 梳理一下目前MySQL维度表的索引情况,当然网上也有其他博客专门讲MySQL索引的,我这边只是梳理一下目前的索引状况而已 2单列索引 2.1 索引截图 2.2 建表语句 3 联合索引 3.1 索引截图 3.2 建表语句 4 参考的优秀博客 http://t.csdnimg.cn/ZF7…

使用LangChain和GPT-4,创建Pandas DataFrame智能体

大家好,数据分析和数据处理是数据科学领域每天都在进行的基本任务。高效和快速的数据转换对于提取有意义的见解和基于数据做出明智决策至关重要。其中最受欢迎的工具之一是Python库Pandas,它提供了一个功能强大的DataFrame工具,使用灵活直观的…

并发编程之ThreadLocal使用及原理

ThreadLocal主要是为了解决线程安全性问题的 非线程安全举例 public class ThreadLocalDemo {// 非线程安全的private static final SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static Date parse(String strDate) throws ParseExc…

力扣2- 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 …

Linux配置程序后台运行(前后台来回切换)

Linux配置程序后台运行 在日常开发过程中,会遇到我们在前台运行程序,此时我们临时有事,但不能关闭终端,否则程序就会在电脑熄屏(终端session断开后)停止运行。 那么作为一个合格的开发,就必须要…

Redis-更新策略,缓存穿透,缓存雪崩,缓存击穿

Redis-更新策略,缓存穿透,缓存雪崩,缓存击穿 1.缓存更新 策略 淘汰策略超时剔除主动更新 更新策略:先修改数据库还是先删除缓存 结论:先修改数据库,因为缓存的操作比较快,容易产生数据不一致更新缓存还是删除缓存? …

字符串转换为List<String>时候抛出异常:com.alibaba.fastjson2.JSONException: TODO : s

前言: 一个字符串想要能够转换为 List,其本身必须是具备 List 属性的字符串。 问题现象: 项目中需要对第三方接口返回的字符串转换为 List,就想到了使用 fastjson 来处理。 代码如下: Object obj data.get(SignC…

Canal介绍原理及安装

Canal 扩展篇 1.Canal介绍、 链接: https://github.com/alibaba/canal Canal 主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费,工作原理如下: Canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave &am…

启动nginx时报错:signal process started

解决方案,直接使用该命令启动,指向nginx.conf配置文件: nginx -c /www/wdlinux/nginx/conf/nginx.conf 启动成功:

JD抓包 | 安卓app抓包

去年11月份左右搞过一次安卓抓包, 搞了很久试了很多方法, 才弄好. 时隔半年, 安卓抓包依然是令我头疼的问题 这次简单记录一下过程(细节太多我也说不清) JD的有效信息接口通常是以下这样的, 其他的接口并没有返回太多"有用"的信息 https://api.m.jd.com/client.act…

使用 Prometheus 在 KubeSphere 上监控 KubeEdge 边缘节点(Jetson) CPU、GPU 状态

作者:朱亚光,之江实验室工程师,云原生/开源爱好者。 KubeSphere 边缘节点的可观测性 在边缘计算场景下,KubeSphere 基于 KubeEdge 实现应用与工作负载在云端与边缘节点的统一分发与管理,解决在海量边、端设备上完成应…

AI来了,Spring还会远吗?(Spring AI初体验)

目录 一、创建项目二、first demo1、application.properties2、ChatController3、结果 三、个人思考 一、创建项目 官方文档的Getting Started 最低要求:JDK17 阿里云的Server URL(https://start.aliyun.com/)搜不到Spring AI,…

『VUE』17. Dom与模板引用(详细图文注释)

目录 回顾之前的操作ref 属性借助dom使用原生js总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 回顾之前的操作 之前的这些操作都是我们使用vue为我们渲染的对象,再来操作dom 内容改变{{ 模板语法 }}属性改变 v-bind:添加事…

稀碎从零算法笔记Day49-LeetCode:设计哈希集合

题型:模拟 链接:705. 设计哈希集合 - 力扣(LeetCode) 来源:LeetCode 题目描述 不使用任何内建的哈希表库设计一个哈希集合(HashSet)。 实现 MyHashSet 类: void add(key) 向哈…

LangChain入门:14.LLMChain:最简单的链的使用

摘要 本文将介绍LangChain库中LLMChain工具的使用方法。LLMChain将提示模板、语言模型(LLM)和输出解析器整合在一起,形成一个连贯的处理链,简化了与语言模型的交互过程。我们将探讨LLMChain的技术特点、应用场景以及它解决的问题…

PostgreSQL入门到实战-第三十弹

PostgreSQL入门到实战 PostgreSQL教程网站官网地址PostgreSQL概述更新计划 PostgreSQL教程网站 https://www.postgresqltutorial.com/ 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://www.postgresql.org/PostgreS…

OpenHarmony实战开发-Actor并发模型对比内存共享并发模型

内存共享并发模型指多线程同时执行复数任务,这些线程依赖同一内存并且都有权限访问,线程访问内存前需要抢占并锁定内存的使用权,没有抢占到内存的线程需要等待其他线程释放使用权再执行。 Actor并发模型每一个线程都是一个独立Actor&#xf…

MySQL limit N offset M 速度慢?来实际体验下

直接开始 有一张表:trade_user,表结构如下: mysql> desc trade_user; ------------------------------------------------------------------ | Field | Type | Null | Key | Default | Extra | -------------…

wpf下RTSP|RTMP播放器两种渲染模式实现

技术背景 在这篇blog之前,我提到了wpf下播放RTMP和RTSP渲染的两种方式,一种是通过控件模式,另外一种是直接原生RTSP、RTMP播放模块,回调rgb,然后在wpf下渲染,本文就两种方式做个说明。 技术实现 以大牛直…

群晖双硬盘实时备份(WebDAV Server+Cloud Sync)

安装和设置 WebDAV Server WebDAV 是一种基于HTTP的协议扩展,它允许用户在远程Web服务器上进行文档的编辑和管理,就如同这些文件存储在本地计算机上一样。使用WebDAV,用户可以创建、移动、复制和修改文件和文件夹。 安装和设置 Cloud Sync…