线程(Thread)

news2024/9/23 5:32:27

目录

线程(Thread)

线程的创建方式 实现方式

Runnable和Callable的区别

线程的命名和优先级

线程的六种状态

线程的插队

线程的中断

线程的让出

守护线程

设置线程为守护线程

sleep()和wait()的区别

线程的同步synchronized锁

语法格式

实现原理

锁升级(锁优化、所膨胀)

线程安全的案例

ReentrantLock锁

并发集合

CopyOnWriteArrayList

思想

并发修改时保证线程安全

并发读取

CopyOnWriteArraySet

BlockingQueue阻塞队列

ArrayBlockingQueue:有界队列

LinkedBlockingQueue:无界队列

ConcurrentHashMap

线程池

常用方法

执行流程

配置参数

拒绝策略

常用线程池


线程(Thread)

线程的创建方式 实现方式

创建方式只有一种:通过Thread创建

实现方式有四种分别是:

  1. 继承Thread类实现

  2. 传入Runnable接口实现类实现

  3. 传入Callable接口实现类实现(要用FutureTask转化为runnable)

  4. 通过线程池实现

Runnable和Callable的区别

  1. runnable接口中的run()方法没有返回值,callable接口中的call()方法有返回值

  2. callable接口实现类中的run方法允许异常向上抛出,可以在内部处理,runnable接口实现类中run方法的异常必须在内部处理,不能向上抛出。

线程的命名和优先级

命名

  1. 在实例化Thread时传入线程名

  2. setName()方法设置线程名

优先级:setPriority()方法设置,(最大10,最小1,默认5)

线程的六种状态

线程创建后为new状态,start()启动后进入runnable可运行状态,run()方法执行结束后进入terminated终止状态,runnable有三个分支状态,当多个线程竞争时,没有获取到锁的线程进入blocked阻塞状态。调用Object.wait()方法和Thread.join()方法后会进入waiting等待状态,调用notify()方法唤醒线程重新进入runnable状态。调用Thread.join(时间值)、Object.wait(时间值)、Thread.sleep(时间值)等方法进入timed_waiting计时,等待状态时间结束后恢复runnable可运行状态。

线程的插队

调用 join() 方法实现插队。

底层通过调用Object的wait方法实现,因为线程在die的时候会自动调用自身的notifyAll方法,来释放所有的资源和锁。

线程的中断

interrupt()

修改中断状态为true,抛出InterruptedException,执行结束。

线程的让出

yield() 让出一次

守护线程

设置线程为守护线程

通过 setDaemon(true) 方法设置

守护线程是用来为用户线程服务的,当一个程序中的所有用户线程都结束之后,无论守护线程是否在工作都会跟随用户线程一起结束。

sleep()和wait()的区别

  1. 休眠过程中,当前线程不会让出持有的"锁",等待过程中,当前线程会让出持有的"锁"

线程的同步synchronized锁

线程安全问题:多个线程同时访问竞争一个资源时,会导致数据损坏不一致。

保证一段代码的原子性就是通过加锁和解锁实现的,实现线程的同步安全,参数对象一致则使用同一个锁。

            synchronized (mutex) {
                Counter.count-=1;
            }

synchronized是一个关键字

语法格式

代码块:自定义对象作为锁

普通方法前:this,代表调用该方法的对象

静态方法前:该静态类Class对象

实现原理

1.通过Monitorenter和Monitorexit两个指令实现

2.通过monitor监视器机制实现线程同步

WaitSet:线程等待区

EntryList:线程阻塞区

Owner:线程拥有者

锁升级(锁优化、所膨胀)

在JDK1.6之前,synchronized性能开销较大;在JDK1.6之后,对synchronized进行了优化,它会自动根据程序的执行情况,自动进行锁的升级:偏向锁->轻量级锁->重量级锁

偏向锁(偏斜锁):只有一个线程访问时,使用偏向锁,通过Owner记录线程ID实现

轻量级锁:出现多个线程访问时(没有并发),使用轻量级锁,通过CAS实现

重量级锁:出现多个线程并发访问时,使用重量级锁。由于重量级锁,使用操作系统的互斥锁实现。(使用互斥锁,从“用户态”切换至“内核态”,带来性能开销,所以性能相对较差)

线程安全的案例

可变字符串的线程安全: StringBuffer : 线程安全(在改变字符串内容的方法上使用synchronized同步锁),性能较差

StringBuilder:线程不安全,性能较好

集合类的线程安全(使用synchronized关键字实现线程安全)

List接口的线程安全实现类:Vector,Stack

Map接口的线程安全实现类:Hashtable

ReentrantLock锁

1.ReentrantLock是核心类库提供的锁实现类,实现了Lock接口,通过lock()方法加锁,unlock()方法释放锁。

2.通过trylock()方法支持获取锁的尝试机制

3.支持公平锁和非公平锁,内部通过AQS机制实现

ReentrantLock实现线程安全的案例

CopyOnWriteArrayList

ArrayBlockingQueue

并发集合

List Set Map Queue

CopyOnWriteArrayList

思想

修改时将原数组内容复制Copy到新数组内,在新数组内修改,然后替换

并发修改时保证线程安全

通过ReentrantLock实现多个线程并发修改时的线程安全同步(添加元素的同时,不允许删除)

添加新元素:list.add("")

按照指定下标替换元素:list.set(index, element)

按照指定下标删除元素:list.remove(0)

并发读取

没有加锁,允许多个线程同时并发读取;但是读取时,可能产生脏读(读取的同时,允许写入操作)。

CopyOnWriteArraySet

内部通过一个CopyOnWriteArrayList实现

BlockingQueue阻塞队列

阻塞队列:有两个线程,分别进行读写(task和put)操作;读取时,不允许写入,如果队列为空,则读取线程阻塞;写入时,不允许读取,如果队列已满,则写入线程阻塞;

经常用于生产消费场景

ArrayBlockingQueue:有界队列

LinkedBlockingQueue:无界队列

ConcurrentHashMap

JDK1,7:通过分段锁实现线程安全

JDK1,8:通过 synchronized+CAS实现线程安全

当产生哈希冲突时,通过synchronized将根节点作为锁,进行线程的同步安全

在没有产生哈希冲突时,通过CAS进行无锁化操作,降低synchronized进行线程同步操作所引发的性能下降

线程池

常用类和接口

ExecutorService接口:线程池的操作

Executors类:工具类,提供了常见线程池的封装

ThreadPoolExecutor类:具体线程池实现类

常用方法

void execute(Runnable command):提交线程任务

Future<T> submit(Callable<T> task):提交线程任务,可以获取线程执行结果

void shutdown():将线程池中的线程任务执行完毕后,关闭线程池

List<Runnable> shutdownNow():立刻关闭线程池,并返回未完成的线程任务

执行流程

  1. 提交线程任务,分配空闲线程

  2. 判断“工作线程数”是否超出“核心线程数”,如果未超出,则创建新线程;

  3. 如果超出,将线程任务存入工作队列

  4. 如果工作队列已满,判断判断“工作线程数”是否超出“最大线程数”,如果未超出,则创建新线程

  5. 如果超出,则执行拒绝策略

配置参数

核心线程数

最大线程数

线程存活时间

工作队列

线程工厂

拒绝策略

AbortPolicy(默认拒绝策略):丢弃当前线程任务,并抛出RejectedExecutionException

AbortPolicy:丢弃当前线程任务

DiscardOldestPolicy:丢弃工作队列中最早入队的线程任务

CallerRunsPolicy:由当前调用线程处理执行线程任务

常用线程池

Executors.newFixedThreadPool(3):固定数目的线程池

Executors.newCachedThreadPool():动态数目的线程池(线程被缓存,提供重复使用效率)

Executors.newSingleThreadExecutor():仅包含1个线程的线程池(将大量的线程任务保存至工作队列,然后按照提交顺序,用一条线程依次处理)

Executors.newScheduledThreadPool(5):可以按照时间进行调度执行任务的线程池

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

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

相关文章

在线动漫信息平台

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;Spring Boot框架 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展示 首页 会员后台 管理员…

day-52 下一个排列

思路 从后向前遍历数组&#xff0c;把遍历过的元素加入一个有序链表&#xff0c;没变里一个元素判断链表中是否有元素大于当前遍历元素&#xff0c;如果有&#xff0c;把链表中大于当前遍历元素的元素集合中最小的那一个元素赋给当前元素&#xff0c;然后将链表中剩余元素依次赋…

建造者模式builder

此篇为学习笔记&#xff0c;原文链接 https://refactoringguru.cn/design-patterns/builder 能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象

JavaWeb【day14】--(SpingBoot原理)

SpingBoot原理 在前面十多天的课程当中&#xff0c;我们学习的都是web开发的技术使用&#xff0c;都是面向应用层面的&#xff0c;我们学会了怎么样去用。而我们今天所要学习的是web后端开发的最后一个篇章springboot原理篇&#xff0c;主要偏向于底层原理。 我们今天的课程安…

2-2 opencv实战进阶系列 多边形识别

目录 一、不说废话&#xff0c;先上现象 二、前言 三、思路讲解 step1&#xff1a;用阈值编辑器对图像进行处理。 step2&#xff1a;应用阈值进行二值化 step3&#xff1a;轮廓查找 step4&#xff1a; 显示文字 四、完整代码贴出 五、现象展示 六、结语 一、不说废话&…

在单向链表中找环

在单向链表中找环也是有多种办法&#xff0c;不过快慢双指针方法是其中最为简洁的方法之一&#xff0c;接下来介绍这种方法。 首先两个指针都指向链表的头部&#xff0c;令一个指针一次走一步&#xff0c;另一个指针一次走两步&#xff0c;如果它们相遇了&#xff0c;证明有环…

数据结构(7.2_1)——顺序查找

顺序查找&#xff0c;又叫"线性查找"&#xff0c;通常用于线性表&#xff08;或者顺序表和链表&#xff09;。 算法思想&#xff1a;从头到尾全部查找出来&#xff08;或者反过来也OK&#xff09; 顺序查找的实现 typedef struct {//查找表的数据结构(顺序表)Elem…

再遇“类和对象”

一、类的默认成员函数 默认成员函数就是用户没有显式实现&#xff0c;编译器会自动生成的成员函数称为默认成员函数。一个类&#xff0c;我们不写的情况下编译器会默认生成以下6个默认成员函数&#xff0c;需要注意的是这6个中最重要的是前4个&#xff0c;最后两个取地址重载不…

visio修改默认字体、颜色、形状格式、连接线格式

设计中取消勾选“将主题应用于新建的形状” 在开发工具中打开绘图资源管理器&#xff0c;并分别修改纯文本、连接线、主题的样式

文本转化为声音

在许多场景下需要将文本转化为MP3格式&#xff0c;本文将实现文本转化为声音&#xff0c;并且将声音保存为MP3格式。本文一朱自清的《春》为例&#xff0c;要实现阅读《春》并且转化为mp3格式的音频文件。 1 导入包 import pyttsx3 from docx import Document def read_word_…

ubuntu内核升级后的问题修复

文章目录 需求当前环境禁止内核更新安装内核修复/usr/include/dlocate 测试 需求 升级后的常见问题 驱动程序不兼容: 新内核版本可能导致某些硬件驱动程序不再兼容&#xff0c;尤其是专有驱动程序或第三方驱动程序。启动问题:内核更新可能导致启动问题&#xff0c;例如无法启动…

《创新电力巡检,机器人铸就安全高效未来》

近年来&#xff0c;我国电力建设投资额持续波动增长&#xff0c;至2023年底&#xff0c;全国电力工程投资总额高达14950亿元&#xff0c;同比增长22%。其中&#xff0c;电源工程建设和电网工程建设投资均达到新的高度。在这一背景下&#xff0c;电力行业对巡检工作的要求也日益…

苹果iOS/ iPadOS18 RC 版、17.7 RC版更新发布

iPhone 16 / Pro 系列新机发布后&#xff0c;苹果一同推出了 iOS 18 和 iPadOS 18 的 RC 版本&#xff0c;iOS 18 RC 的内部版本号为22A3354&#xff0c;本次更新距离上次发布 Beta/RC 间隔 12 天。 在 iOS 18 中&#xff0c;苹果给我们带来了 Apple Intelligence&#xff0c;这…

springboot高校兼职平台-计算机毕业设计源码65602

摘要 基于SpringBoot框架的高校兼职平台专注于为普通用户提供便捷的兼职信息服务。该平台包括普通用户功能、系统内容浏览、通知公告查看与论坛交流互动、兼职信息搜索与申请、个人中心管理和管理员权限管理等模块。利用SpringBoot框架实现了模块化开发和依赖注入&#xff0c;结…

驱动与应用的编译

无论是去驱动编译&#xff0c;还是应用编译&#xff0c;本质上都是用gcc这个工具&#xff0c;后面跟不同的参数来完成 驱动编译 放入内核编译 obj-y $(TARGET_SDK).o&#xff0c;就会直接将驱动编译成.o。供内核链接的时候&#xff0c;链接进整个内核镜像&#xff1b; obj-m…

Flutter自定义Icon的简易使用(两种)

方式一&#xff1a;利用第三方库&#xff08;建议&#xff09; 1、在阿里图标库(iconfont-阿里巴巴矢量图标库)上&#xff0c;加载购物车后&#xff0c;点击“下载素材”svg。 2、把下载的图片放入asstes目录下。​​​​​​​ 3、修改yaml配置文件&#xff0c;设置Icon图标所…

动态单窗口IP代理:提升网络操作的灵活性和安全性

互联网时代&#xff0c;各种网络工具层出不穷&#xff0c;而动态单窗口IP代理无疑成为了近年来的热门话题。今天&#xff0c;我们就来聊聊这个神奇的工具&#xff0c;看看它到底有什么独特之处。 什么是动态单窗口IP代理&#xff1f; 动态单窗口IP代理&#xff0c;顾名思义&a…

基于CogVideoX-2B的国产Sora文字一键生成视频

CogVideoX-2B是由THUDM团队开发的先进视频生成模型,利用最前沿的变压器技术,实现从文本到视频的高质量转换。无论是研究人员还是开发者,CogVideoX-2B都提供了一个强大的开源工具,用于视频合成和AI驱动的媒体创作。 本教程将详细介绍如何使用CogVideoX-2B,包括环境设置、模…

simd vs simt

GPU架构及运行机制学习笔记_gpu结构-CSDN博客 SIMD (Single Instruction, Multiple Data) 和 SIMT (Single Instruction, Multiple Threads) SIMD 架构是指在同一时间内对多个数据执行相同的操作&#xff0c;适用于向量化运算。例如&#xff0c;对于一个包含多个元素的数组&am…

震惊!立体连接:开启商业新模式的流量密码

摘要&#xff1a;本文深度揭秘在当今商业环境中立体连接的重大意义&#xff0c;揭示最佳匹配线下、社群和网络三度空间来实现认知、交易、关系三大功能的神奇之处。通过剖析开源链动 2 1 模式、AI 智能名片、S2B2C 商城小程序等元素在三度空间的运用&#xff0c;阐述如何达成最…