进程与线程、线程创建、线程周期、多线程安全和线程池(ThreadPoolExecutor)

news2024/9/30 17:26:30

目录

    • 进程与线程
    • 线程和进程的区别是什么?
    • 线程分两种:用户线程和守护线程
    • 线程创建四种方式
      • run()和start()方法区别:
      • 为什么调用 start() 方法时会执行 run() 方法,为什么不能直接调用 run() 方法?
      • Runnable接口和Callable接口有何区别
    • 线程声明周期的6种状态
    • 如何保证多线程安全的?
      • 什么是线程安全?
      • 如何保证多线程安全的
      • 线程同步和线程互斥的区别
      • 如何同步线程?
      • 如何避免线程死锁?
        • 死锁的四个必要条件:
        • 避免线程死锁
      • 如何优化多线程程序的性能?
    • 什么是线程池?它的优点?
    • 为什么要使用线程池?
    • 创建线程池:ThreadPoolExecutor
    • ThreadPoolExecutor构造函数七大参数
      • 拒绝任务策略:
    • 乐观锁和悲观锁的理解?

进程与线程

什么进程?
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

什么是线程?
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

  • 对于单核CPU而言:多线程就是一个CPU在来回的切换,在交替执行。
  • 对于多核CPU而言:多线程就是同时有多条执行路径在同时(并行)执行,每个核执行一个线程,多个核就有可能是一块同时执行的。

线程和进程的区别是什么?

进程是资源分配的最小单位,而线程是程序执行的最小单位。一个进程可以包含多个线程,线程之间共享进程的资源,但每个线程都有自己的栈空间和寄存器

线程分两种:用户线程和守护线程

用户线程:如果主线程main停止掉,不会影响用户线程,用户线程可以继续运行。
守护线程:为其他线程服务的,如果主线程死亡,守护线程如果没有执行完毕也要跟着一块死,GC垃圾回收线程就是守护线程

线程创建四种方式

  1. 继承 Thread,重写run方法
  2. 实现 Runable,重写run方法
  3. 实现 Callable,重写run方法
  4. Executors工具类创建线程池
    一般推荐使用 ThreadPoolExecutor创建线程池

run()和start()方法区别:

run():仅仅是封装被线程执行的代码,直接调用是普通方法
start():首先启动了线程,这时此线程处于就绪(可运行)状态,然后再由jvm去调用该线程的run()方法。

为什么调用 start() 方法时会执行 run() 方法,为什么不能直接调用 run() 方法?

调用 start 方法方可启动线程并使线程进入就绪状态,而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。

Runnable接口和Callable接口有何区别

相同点:

  • Runnable和Callable都是接口
  • 都可以编写多线程程序
  • 都采用Thread.start()启动线程

不同点:

  • Runnable接口run方法无返回值,Callable接口call方法有返回值,是个泛型,和Futrue和FutureTask配合用来获取异步执行结果。
  • Runable接口run方法只能抛出运行时的异常,且无法捕获处理;Callable接口call方法允许抛出异常,可以获取异常信息。

线程声明周期的6种状态

  1. 创建:又称初始化状态,这个时候Thread才刚刚被new出来,还没有被启动。

  2. 可运行:表示已经调用Thread的start方法启动了,随时等待CPU的调度,此状态又被称为就绪状态。

  3. 阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态

    • 阻塞的情况分三种:
      (一). 等待阻塞:运行状态中的线程执行 **wait()**方法,JVM会把该线程放入等待队列(waitting queue)中,使本线程进入到等待阻塞状态;
      (二). 同步阻塞:线程在获取 synchronized 同步锁失败(因为锁被其它线程所占用),,则JVM会把该线程放入锁池(lock pool)中,线程会进入同步阻塞状态;
      (三). 其他阻塞: 通过调用线程的 **sleep()**或 **join()**或发出了 I/O 请求时,线程会进入到阻塞状态。当 sleep()状态超时、join()等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入就绪状态。
  4. 等待:获取锁对象后,调用wait()方法,释放锁进入无线等待状态

  5. 计时等待:调用sleep(参数)或wait(参数)后线程进入计时状态,睡眠时间到了或wait时间到了,再或者其它线程调用notify并获取到锁之后开始进入可运行状态,避免了无期限的等待。

  6. 死亡:表示已经正常执行完线程体run()中的方法了或者因为没有捕获的异常而终止run()方法了。
    在这里插入图片描述

如何保证多线程安全的?

什么是线程安全?

线程安全:指某个方法在多线程环境被调用,能够正确处理多线程之间的共享变量,是程序功能正确完成。

如何保证多线程安全的

  1. 使用安全类,比如 java.util.concurrent 下的类,使用原子类AtomicInteger
  2. 使用自动锁 synchronized。
  3. 使用手动锁 Lock。

线程同步和线程互斥的区别

线程同步:当一个线程对共享数据进行操作的时候,在没有完成相关操作时,不允许其它的线程来打断它,否则就会破坏数据的完整性,必然会引起错误信息。

线程互斥:线程互斥是站在共享资源的角度上看问题,例如某个共享资源规定,在某个时刻只能一个线程来访问我,其它线程只能等待,知道占有的资源者释放该资源,线程互斥可以看作是一种特殊的线程同步。

如何同步线程?

可以使用互斥锁、条件变量、信号量等机制来同步线程。互斥锁用于保护共享资源,条件变量用于线程之间的通信,信号量用于控制并发访问。

如何避免线程死锁?

死锁的四个必要条件:

  1. 互斥条件:进程对所分配到的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。

  2. 请求和保持条件:进程已经获得了至少一个资源,但又对其他资源发出请求,而该资源已被其他进程占有,此时该进程的请求被阻塞,但又对自己获得的资源保持不放。

  3. 不可剥夺条件:进程已获得的资源在未使用完毕之前,不可被其他进程强行剥夺,只能由自己释放。

  4. 循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。

避免线程死锁

预防死锁的方式就是打破四个必要条件中的任意一个即可。

避免线程死锁的方法包括:避免嵌套锁,按照固定的顺序获取锁,使用超时机制,避免资源竞争等。此外,还可以使用死锁检测工具来检测和解决死锁问题。

如何优化多线程程序的性能?

可以采用以下方法来优化多线程程序的性能:避免线程之间的竞争,减少锁的使用,使用无锁数据结构,使用线程池等。此外,还可以使用性能分析工具来找出程序的瓶颈,进行优化。

什么是线程池?它的优点?

事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。

  • 优点
    • 降低资源消耗:重用存在的线程,减少对象创建销毁的开销。
    • 提高响应速度:可有效的控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
    • 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
    • 附加功能:提供定时执行、定期执行、单线程、并发数控制等功能。

为什么要使用线程池?

如果我们在方法中直接new一个线程来处理,当这个方法被调用频繁时就会创建很多线程,不仅会消耗系统资源,还会降低系统的稳定性,一不小心把系统搞崩了。合理的使用线程池,则可以避免把系统搞崩的窘境,这说一下线程池的好处:降低资源消耗、提高响应速度和提高线程的可管理性。

创建线程池:ThreadPoolExecutor

Executors和ThreaPoolExecutor创建线程池的区别
Executors 各个方法的弊端:

  • newFixedThreadPool 和 newSingleThreadExecutor:
    主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。
  • newCachedThreadPool 和 newScheduledThreadPool:
    主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

ThreadPoolExecutor创建线程池方式只有一种,就是走它的构造函数,参数自己指定。

ThreadPoolExecutor构造函数七大参数

  1. 核心线程数(corePoolSize ): 线程数定义了最小可以同时运行的线程数量;
  2. 最大线程数(maximumPoolSize ):线程池中允许存在的工作线程的最大数量;
  3. 允许线程空闲时间(keepAliveTime):线程池中的线程数量大于核心线程数的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 空闲时间才会被回收销毁;
  4. 时间单位(unit ):参数的时间单位;
  5. 队列(workQueue):当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,任务就会被存放在队列中;
  6. 线程工厂(threadFactory):为线程池提供创建新线程的线程工厂;
  7. 拒绝策略(handler ):线程池任务队列超过最大线程数之后的拒绝策略,默认直接抛出异常。
    在这里插入图片描述

拒绝任务策略:

  • 中止策略(AbortPolicy):抛出 RejectedExecutionException来拒绝新任务的处理;
  • 调用者策略(CallerRunsPolicy):调用执行自己的线程运行任务;
  • 抛弃策略(DiscardPolicy):什么都不做,直接丢弃掉;
  • 抛弃最老最老策略(DiscardOldestPolicy):丢弃最早的未处理的任务请求。

乐观锁和悲观锁的理解?

乐观锁:每个去拿数据的时候都认为别人不会修改,所以不会都不会上锁,但是在更新的时候会判断一下在此期间有没有去更新这个数据。所以乐观锁使用了多读的场合,这样可以提高吞吐量,像数据库提供的类似write_condition机制,都是用的乐观锁。

悲观锁:总是认为出现问题,每次去拿数据的时候都会认为有人会修改,所以每次在拿数据的时候都会上锁。这样别的对象想拿到数据,那就必须堵塞,直到拿到锁。传统的关系型数据库用到了很多这种锁机制,比如读锁,写锁,在操作之前都会先上锁,再比如Java的同步代码块synchronized/方法用的也是悲观锁。

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

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

相关文章

最强实战,接口自动化测试Python3+Requests+Unittest+ddt框架封装(详细)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 接口自动化测试框…

RDP远程桌面服务的RD授权过期解决方法

RDP远程桌面服务的RD授权过期解决方法 一、打开远程桌面会话主机配置二、打开远程桌面授权模式属性三、选择远程桌面授权模式四、添加许可证服务器五、选择确定保存设置六、RD授权设置成功七、查看“授权诊断” 一、打开远程桌面会话主机配置 二、打开远程桌面授权模式属性 双…

35岁,不是体能衰老的分界线!

35岁,不是体能衰老的分界线 1. 35岁以上求职者同比增长14.9%,体能下滑成为35岁以上年龄群体的标签。 2. 35岁人群开始感觉经常失眠、腰背痛和肥胖,体力不济可能是常年累积的不规律作息和饮食习惯导致。 3. 35岁以后体能下滑,无法高…

视频添加字幕

1、依靠ffmpeg 命令 package zimu;import java.io.IOException;public class TestSrt {public static void main(String[] args) {String videoFile "/test/test1.mp4";String subtitleFile "/test/test1.SRT";String outputFile "/test/testout13…

openpnp - 吸嘴站(Nozzle Tip Changer)的选择

文章目录 openpnp - 吸嘴站(Nozzle Tip Changer)的选择概述磁铁吸嘴库带抱轴的吸嘴库我的吸嘴库选择我的吸嘴库实现 - 磁铁吸嘴库吸嘴座主体吸嘴座上盖我的吸嘴库实现 - 带抱轴的吸嘴库吸嘴座主体拔吸嘴时的受力挡板抱轴层上盖备注END openpnp - 吸嘴站(Nozzle Tip Changer)的选…

同城预约上门小程序开发:为用户带来便捷与个性化的服务体验“

上门服务小程序开发具有许多优势,下面我将介绍一些重要的优点。   方便快捷:上门服务小程序可以让用户随时随地通过手机进行预约和安排上门服务。无需等待电话回复或亲自前往实体店面,用户可以直接在小程序中选择时间、服务类型和地点&…

openGauss学习笔记-29 openGauss 高级数据管理-UNION子句

文章目录 openGauss学习笔记-29 openGauss 高级数据管理-UNION子句29.1 语法格式29.2 示例29.2.1 UNION29.2.2 UNION ALL openGauss学习笔记-29 openGauss 高级数据管理-UNION子句 UNION计算多个SELECT语句返回行集合的并集。UNION内部的SELECT语句必须拥有相同数量的列&#…

《剑指offer》(4)二叉树篇

二叉树深度有两种递归思路: (1)递归返回当前的深度,当root是空时,返回0 (2)将当前深度和节点一起传入递归,设置全局变量,每经过一个节点就更新全局变量的值。 方法一&a…

控制台窗口和powershell运行服务会卡住的解决办法

问题描述 在 windows 环境下开发的时候,使用 PowerShell 执行 python.exe test.py 等命令经常会出现程序会卡在不动的问题。这时候需要到控制台按一下回车程序才会继续往下执行。 解决办法 原因: 控制台开启了快速编辑模式的情况下,如果鼠标选中了文本…

弘扬“两弹一星”精神,勇攀科学技术高峰——道本科技商业大学党日活动圆满落幕

2023年8月2日,道本科技与商业大学携手举办了一场主题为“弘扬‘两弹一星’精神,勇攀科学技术高峰”的党日活动。本次活动旨在了解党领导下的中国核工业发展历程,传承和弘扬“两弹一星”精神,同时展示道本科技创新产品,…

【力扣】链表题目总结

文章目录 链表基础题型一、单链表翻转、反转、旋转1.反转链表2.反转链表II——反转部分链表3.旋转链表4.K个一组翻转链表5.反转偶数长度组的节点 二、删除单链表中的结点1.删除链表的结点2.删除未排序链表中的重复节点3.删除已排序链表中的重复元素I——重复元素只剩下一个4.删…

带你简单认识淘宝 API 接口,API接口适用场景和业务类型

淘宝 API 接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范。通过开放接口,开发者可以不改变现有系统,直接在原有系统上实现新功能。该规范于 2007 年发布,是目前业界唯一完整覆盖电商系统各相关业务领域的接口标准…

C语言假期作业 DAY 13

一、选择题 1、如果 x2014 ,下面函数的返回值是( ) int fun(unsigned int x) { int n 0; while(x 1) { n; x x | (x 1); } return n; } A: 20 B: 21 C: 23 D 25 答案解析 正确答案:C 这个作用是对整型中0的个数进行统计&…

安卓手机录屏怎么把小白点去掉?试试这种方法

随着安卓手机功能的不断升级,录屏已经成为了一项基本功能。然而,当我们录制完视频后,常常会发现视频中有许多小白点,影响了视频的美观度。那么,如何去除这些小白点呢?本文将为大家介绍几种简单易行的方法。…

Linux操作系统块设备参数调优

目录 一、队列深度 二、调度算法 三、预读量 四、I/O对齐 一、队列深度 队列深度决定了给块设备写I/O的最大并发数,对于Linux系统,默认值为128,一般情况下不建议用户修改此参数。用户可以使用cat命令查询当前块设备队列深度。 linux-ob3a…

Arthas GC日志-JVM(十八)

上篇文章说jvm的实际运行情况。 Jvm实际运行情况-JVM(十七) Arthas介绍 因为arthas完全是java代码写的,我们直接用命令启动: Java -jar arthas-boot.jar 启动成功后,选择我们项目的进程。 进入我们可用dashboard…

ATFX汇评:非农就业报告来袭,汇市或迎剧烈波动

ATFX汇评:美国非农就业报告每月发布一次,其中非农就业人口和失业率两项数据最受关注。7月季调后非农就业人口,将于今日20:30公布,前值为20.9万人,预期值20万人;7月失业率,同一时间公布&#xff…

文字转语音

键盘获取文字,转化为语音后保存本地 from win32com.client import Dispatch from comtypes.client import CreateObject from comtypes.gen import SpeechLib speakerDispatch(SAPI.SpVoice) speaker.Speak(请输入你想转化的文字) datainput(请输入:)#s…

【二等奖方案】Web攻击检测与分类识别赛题「机器学习」团队解题思路

2022 CCF BDCI 数字安全公开赛 赛题「Web攻击检测与分类识别」 地址:http://go.datafountain.cn/4Zj 机器学习战队 获奖方案 团队简介 我们团队由五名成员组成,对机器学习都非常感兴趣,同时在机器学习领域有着丰富的实战经验&#xff0c…

Teams Room视频会议室方案

需求背景: 适合在40平米的会议室参加Teams视频会议,会议桌周围可以坐20人,要求: 1,操作简单,一键入会Teams Room; 2,任何人带上自己的笔记本电脑,可以分享电脑画面&#…