014_多线程

多线程

  • 多线程
  • 创建线程
    • 方式一:继承Thread类
    • 方式二:实现Runable接口
    • 方式三:实现Callbale接口
  • Thread的常用方法
  • 线程安全
  • 线程同步
    • 方式一:同步代码块
    • 同步方法
    • 方式三:Lock锁
  • 线性池
    • 创建线程池
    • 处理Runnable任务
    • 处理Callable任务
    • 通过Executors创建线程池
  • 并发/并行
    • 并发
    • 并行

多线程

  • 线程(Thread)是一个程序内部的一条执行流程。
  • 程序中如果只有一条执行流程,那这个程序就是单线程的程序。
  • 多线程是指从软硬件上实现的多条执行流程的技术(多条线程由CPU负责调度执行)。

创建线程

  • 启动线程必须是调用start方法,不是调用run方法。
    • 直接调用run方法会当成普通方法执行,此时相当于还是单线程执行
    • 只有调用start方法才是启动一个新的线程执行。
  • 不要把主线程任务放在启动子线程之前。
    • 这样主线程一直是先跑完的,相当于是一个单线程的效果了。

方式一:继承Thread类

  • 定义一个子类MyThread继承线程类java.lang.Thread,重写run()方法
  • 创建MyThread类的对象
  • 调用线程对象的start()方法启动线程(启动后还是执行run方法的)
  • 优缺点
    • 优点:编码简单
    • 缺点:线程类已经继承Thread,无法继承其他类,不利于功能的扩展。

方式二:实现Runable接口

  • 定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法
  • 创建MyRunnable任务对象
  • 把MyRunnable任务对象交给Thread处理。
  • 调用线程对象的start()方法启动线程
  • 优缺点
    • 优点:任务类只是实现接口,可以继续继承其他类、实现其他接口,扩展性强。
    • 缺点:需要多一个Runnable对象。
Thread****类提供的构造器说明
public Thread(Runnable target)封装Runnable对象成为线程对象
  • 匿名内部类写法
    • 可以创建Runnable的匿名内部类对象。
    • 再交给Thread线程对象。
    • 再调用线程对象的start()启动线程。

方式三:实现Callbale接口

  • 创建任务对象
    • 定义一个类实现Callable接口,重写call方法,封装要做的事情,和要返回的数据。
    • 把Callable类型的对象封装成FutureTask(线程任务对象)。
  • 把线程任务对象交给Thread对象。
  • 调用Thread对象的start方法启动线程。
  • 线程执行完毕后、通过FutureTask对象的的get方法去获取线程任务执行的结果。
  • 优缺点
    • 优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强;可以在线程执行完毕后去获取线程执行的结果。
    • 缺点:编码复杂一点。
  • FutureTask的API
FutureTask提供的构造器说明
public FutureTask<>(Callable call)把Callable对象封装成FutureTask对象。
FutureTask提供的方法说明
public V get() throws Exception获取线程执行call方法返回的结果。

Thread的常用方法

Thread提供的常用方法说明
public void run()线程的任务方法
public void start()启动线程
public String getName()获取当前线程的名称,线程名称默认是Thread-索引
public void setName (String name)为线程设置名称
public static Thread currentThread ()获取当前执行的线程对象
public static void sleep(long time)让当前执行的线程休眠多少毫秒后,再继续执行
public final void join()…让调用当前这个方法的线程先执行完!
Thread 提供的常见构造器说明
public Thread(String name)可以为当前线程指定名称
public Thread(Runnable target)封装Runnable对象成为线程对象
public Thread(Runnable target, String name)封装Runnable对象成为线程对象,并指定线程名称

线程安全

  • 多个线程,同时操作同一个共享资源的时候,可能会出现业务安全问题。
    • 存在多个线程在同时执行
    • 同时访问一个共享资源
    • 存在修改该共享资源

线程同步

  • 线程同步是线程安全问题的解决方案。
  • 线程同步的核心思想
    • 让多个线程先后依次访问共享资源,这样就可以避免出现线程安全问题。
  • 线程同步的常见方案
    • 加锁:每次只允许一个线程加锁,加锁后才能进入访问,访问完毕后自动解锁,然后其他线程才能再加锁进来。

方式一:同步代码块

  • 作用:把访问共享资源的核心代码给上锁,以此保证线程安全。
    • 对出现问题的核心代码使用synchronized进行加锁
    • 每次只能一个线程占锁进入访问
  • 原理:每次只允许一个线程加锁后进入,执行完毕后自动解锁,其他线程才可以进来执行。
  • 对于当前同时执行的线程来说,同步锁必须是同一把(同一个对象),否则会出bug。
  • 锁对象的使用规范
    • 建议使用共享资源作为锁对象,对于实例方法建议使用this作为锁对象。
    • 对于静态方法建议使用字节码(类名.class)对象作为锁对象。
synchronized(同步锁) {访问共享资源的核心代码
}

同步方法

  • 作用:把访问共享资源的核心方法给上锁,以此保证线程安全。

  • 原理:每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。

  • 同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。

  • 如果方法是实例方法:同步方法默认用this作为的锁对象。

  • 如果方法是静态方法:同步方法默认用类名.class作为的锁对象。

修饰符 synchronized 返回值类型 方法名称(形参列表) {操作共享资源的代码
}

方式三:Lock锁

  • Lock锁是JDK5开始提供的一个新的锁定操作,通过它可以创建出锁对象进行加锁和解锁,更灵活、更方便、更强大。
  • Lock是接口,不能直接实例化,可以采用它的实现类ReentrantLock来构建Lock锁对象。
  • 锁对象建议使用final修饰,防止被别人篡改
  • 释放锁建议将释放锁的操作放到finally代码块中,确保锁用完了一定会被释放

线性池

  • 线程池就是一个可以复用线程的技术。
  • 不使用线性池的问题
    • 用户每发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的, 创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能。
  • 线程池的工作原理
    线程池的基本概念是,在应用程序启动时创建一定数量的线程,并将它们保存在线程池中。当需要执行任务时,从线程池中获取一个空闲的线程,将任务分配给该线程执行。当任务执行完毕后,线程将返回到线程池,可以被其他任务复用。
    • 线程池:{有限的任务队列(WorkQueue)}
    • 工作线程WorkThread进行选择任务队列的对象。
    • 任务接口
      • Runable
      • Callable

创建线程池

  • JDK 5.0起提供了代表线程池的接口:ExecutorService。
  • 方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。
    ExecutorService ——> ThreadPoolExecutor
    • 通过ThreadPoolExecutor创建线程池。
      • 参数一:corePoolSize : 指定线程池的核心线程的数量。
      • 参数二:maximumPoolSize:指定线程池的最大线程数量。
      • 参数三:keepAliveTime :指定临时线程的存活时间。
      • 参数四:unit:指定临时线程存活的时间单位(秒、分、时、天)
      • 参数五:workQueue:指定线程池的任务队列。
      • 参数六:threadFactory:指定线程池的线程工厂。
      • 参数七:handler:指定线程池的任务拒绝策略(线程都在忙,任务队列也满了的时候,新任务来了该怎么处理)
ThreadPoolExecutor类提供的构造器作用
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)使用指定的初始化参数创建一个新的线程池对象
  • 方式二:使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象。

处理Runnable任务

  • ExecutorService的常用方法
方法名称说明
void execute(Runnable command)执行 Runnable 任务
Future submit(Callable task)执行 Callable 任务,返回未来任务对象,用于获取线程返回的结果
void shutdown()等全部任务执行完毕后,再关闭线程池!
List shutdownNow()立刻关闭线程池,停止正在执行的任务,并返回队列中未执行的任务
  • 线程池的注意事项
    • 新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。
      什么时候会拒绝新任务?
    • 核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务。
  • 任务拒绝策略
策略说明
ThreadPoolExecutor.AbortPolicy()丢弃任务并抛出RejectedExecutionException异常。是默认的策略
ThreadPoolExecutor. DiscardPolicy()丢弃任务,但是不抛出异常,这是不推荐的做法
ThreadPoolExecutor. DiscardOldestPolicy()抛弃队列中等待最久的任务 然后把当前任务加入队列中
ThreadPoolExecutor. CallerRunsPolicy()由主线程负责调用任务的run()方法从而绕过线程池直接执行

处理Callable任务

  • 线程池使用ExecutorService的方法处理Callable任务,并得到任务执行完后返回的结果。
    Future<T> submit(Callable<T> command)

通过Executors创建线程池

  • Executors是一个线程池的工具类,提供了很多静态方法用于返回不同特点的线程池对象。
  • 方法的底层,都是通过线程池的实现类ThreadPoolExecutor创建的线程池对象。
方法名称说明
public static ExecutorService newFixedThreadPool(int nThreads)创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程替代它。
public static ExecutorService newSingleThreadExecutor()创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程。
public static ExecutorService newCachedThreadPool()线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了60s则会被回收掉。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)创建一个线程池,可以实现在给定的延迟后运行任务,或者定期执行任务。
  • Executors不是适合做大型互联网场景的线程池方案。
    • 建议使用ThreadPoolExecutor来指定线程池参数,这样可以明确线程池的运行规则,规避资源耗尽的风险。

并发/并行

  • 正在运行的程序(软件)就是一个独立的进程。
  • 线程是属于进程的,一个进程中可以同时运行很多个线程。
  • 进程中的多个线程其实是并发和并行执行的。

并发

  • 进程中的线程是由CPU负责调度执行的,但CPU能同时处理线程的数量有限,为了保证全部线程都能往前执行,CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,这就是并发。

并行

  • 在同一个时刻上,同时有多个线程在被CPU调度执行。

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

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

相关文章

机场跑道异物检测数据集VOC+YOLO格式33793张31类别

数据集分辨率都是300x300,都是贴近地面拍摄&#xff0c;具体看图片 据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;33793 标注数量(xml文件…

Spring Cloud 远程调用

4.OpenFeign的实现原理是什么&#xff1f; 在使用OpenFeign的时候&#xff0c;主要关心两个注解&#xff0c;EnableFeignClients和FeignClient。整体的流程分为以下几个部分&#xff1a; 启用Feign代理&#xff0c;通过在启动类上添加EnableFeignClients注解&#xff0c;开启F…

Unity中使用FMETP STREAM传输实时画面

一、客户端&#xff08;发送端&#xff09; 总体思路&#xff1a;先把画面编码Encoder&#xff0c;再发送给服务端 新建场景&#xff0c;创建一个实体&#xff0c;名为FMnet&#xff0c;添加组件FMNetworkManager&#xff0c;将NetworkType设置为客户端Client&#xff0c;设置…

Baklib三步构建企业内容中台

需求调研构建内容中台 企业内容中台建设的首要环节在于精准识别业务需求与知识管理痛点。通过Baklib 是什么类型的工具的定位分析可知&#xff0c;其作为知识管理中枢&#xff0c;能够系统梳理客户服务场景中的高频咨询、产品文档更新需求及跨部门协作流程。在需求调研阶段&am…

实现抗隐私泄漏的AI人工智能推理

目录 什么是私人AI? 什么是可信执行环境? TEE 如何在 AI 推理期间保护数据? 使用 TEE 是否存在风险? 有哪些风险? Atoma 如何应对这些风险 为什么去中心化网络是解决方案 人工智能推理过程中还有其他保护隐私的方法吗? 私人人工智能可以实现什么? 隐私驱动的应…

一、TorchRec里边的输入输出类型

TorchRec中的输入和输出格式 文章目录 TorchRec中的输入和输出格式前言一、JaggedTensor1.1 核心概念1.2 核心属性&#xff0c;也就是参数1.3 关键操作与方法 二、KeyedJaggedTensor2.1 核心概念2.2 核心属性&#xff0c;也就是参数 3、KeyedTensor总结 前言 TorchRec具有其特…

JAVA实现在H5页面中点击链接直接进入微信小程序

在普通的Html5页面中如何实现点击URL链接直接进入微信小程序&#xff0c;不需要扫描小程序二维码&#xff1f; 网上介绍的很多方法是在小程序后台设置Schema&#xff0c;不过我进入我的小程序后台在开发设置里面 没有找到设置小程序Schema的地方&#xff0c;我是通过调用API接口…

uniapp解决上架华为应用市场审核要求-监听权限的申请

支持android平台全局监听权限的申请。当申请权限时&#xff0c;会在页面顶部显示申请权限的目的。主要解决上架华为应用市场审核要求&#xff1a;APP在调用终端权限时&#xff0c;应同步告知用户申请该权限的目的。 因为如果不提示&#xff0c;你上架应用市场会被打打回来 Tip…

文件IO5(JPEG图像原理与应用)

JPEG图像原理与应用 ⦁ 基本概念 JPEG&#xff08;Joint Photographic Experts Group&#xff09;指的是联合图像专家组&#xff0c;是国际标准化组织ISO制订并于1992年发布的一种面向连续色调静止图像的压缩编码标准&#xff0c;所以也被称为JPEG标准。 同样&#xff0c;JP…

vue3 history路由模式刷新页面报错问题解决

在使用history路由模式时刷新网页提示404错误&#xff0c;这是改怎么办呢。 官方解决办法 https://router.vuejs.org/zh/guide/essentials/history-mode.html

3D激光轮廓仪知识整理(待完善)

文章目录 1.原理和应用场景1.1 相机原理1.1.1 测量原理1.1.2 相机激光器1.1.3 沙姆镜头1.1.4 相机标定1.1.5 中心线提取 1.2 应用场景1.2.1 测量相关应用1.2.2 缺陷检测相关应用 2.相机参数介绍及选型介绍2.1 成像原理2.2 原始图成像2.3 生成轮廓图2.4 相机规格参数2.4.1 单轮廓…

w285药店管理系统的设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

Google Chrome Canary版官方下载及安装教程【适用于开发者与进阶用户】

谷歌浏览器&#xff08;Google Chrome&#xff09;以其高性能、强扩展性和良好的用户体验深受全球用户喜爱。在其多个版本中&#xff0c;Chrome Canary因具备最前沿的功能测试环境&#xff0c;成为开发者和技术探索者的首选。如果你希望第一时间体验Google Chrome最新功能&…

RocketMQ深度百科全书式解析

​一、核心架构与设计哲学​ ​1. 设计目标​ ​海量消息堆积​&#xff1a;单机支持百万级消息堆积&#xff0c;适合大数据场景&#xff08;如日志采集&#xff09;。​严格顺序性​&#xff1a;通过队列分区&#xff08;Queue&#xff09;和消费锁机制保证局部顺序。​事务…

每日一题(小白)暴力娱乐篇19

样例&#xff1a; 6 1 1 4 5 1 4 输出&#xff1a; 56 66 52 44 54 64 分析题意可以得知&#xff0c;就是接收一串数字&#xff0c;将数字按照下标每次向右移动一位&#xff08;末尾循环到第一位&#xff09;&#xff0c;每次移动玩计算一下下标和数字的乘积且累加。 ①接收…

如何应对“最后时刻任务堆积”(鼓包现象)

应对“最后时刻任务堆积”&#xff08;鼓包现象&#xff09;的方法包括&#xff1a;合理规划项目时间表、强化进度跟踪管理、明确任务优先级、有效的资源配置、提升团队沟通效率。其中&#xff0c;强化进度跟踪管理尤为关键。根据项目管理协会&#xff08;PMI&#xff09;的调查…

19C-19.3环境-impdp导入到view时卡死

帮客户导入一个用户时&#xff0c;发现VIEW部分无法进行下去 Processing object type SCHEMA_EXPORT/TABLE/IDENTITY_COLUMN Processing object type SCHEMA_EXPORT/PACKAGE/PACKAGE_SPEC Processing object type SCHEMA_EXPORT/FUNCTION/FUNCTION Processing object type SCH…

一、简单的 Django 服务

一、配置虚拟环境 1.1 创建一个文件夹在导航栏输入cmd打开 1.2 安装依赖两个库 pip install virtualenv virtualenvwrapper-win -i https://pypi.tuna.tsinghua.edu.cn/simple验证是否安装成功 virtualenv --version pip show virtualenvwrapper-win 1.3 创建虚拟环境 mkvi…

道路运输安全员岗位事项有哪些?

道路运输安全员的岗位事项主要包括以下几个方面&#xff1a; 安全制度与计划 参与制定和完善道路运输企业的安全管理制度、安全操作规程等&#xff0c;确保各项安全工作有章可循。协助制定年度安全工作计划和目标&#xff0c;并负责组织实施和监督执行情况&#xff0c;定期对…

潇洒浪: Dify 上传自定义文件去除内容校验 File validation failed for file: re.json

Dify上传文件 添加其他文件类型如 my.myselfsuffix 上传成功 执行报错 File validation failed for file: re.json 解决办法 Notepad 搜索dify源码 注释掉&#xff0c;重启容器 或者直接在容器中修改重启