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

八股文-多线程、并发

八股文-多线程、并发

最近学到了一种方法,可以用于简历项目经验编写以及面试题目的回答

STAR法则:在什么背景下,你需要解决什么问题,你做了啥,得到了什么结果
情境(Situation): 描述你面对的特定情境或背景。
任务(Task): 说明你面临的具体任务或挑战。
行动(Action): 阐述你采取了什么行动来解决问题或完成任务。
结果(Result): 指出你的行动带来了什么结果,以及你取得了什么成就。
参考:https://blog.csdn.net/qq_37037348/article/details/139144523

多线程是啥?为啥要有多线程?

在单个程序中可以同时运行多个线程执行不同的任务。学习了一个操作系统上面运行多个进程的方法,一个进程上面用多个线程管理。计算机最早出现的时候还没有操作系统,程序直接运行在计算机上,这样一个计算机的功能有限,资源利用率也不高。所以就出现了操作系统,通过进程的方式实现一个计算机可以同时运行多个程序,同时一个程序里面又需要处理多种任务,如果所以任务用一个线程来执行,那么多个任务只能排队处理,同样效率低下,无法好好的利用资源(内存、磁盘IO、CPU等)。
并行处理、充分利用资源 → 提高性能和效率、改善用户体验

使用多线程带来的问题?

线程安全问题(一致性问题)、死锁(相互等待)、资源争抢(CPU时间、内存、I/O)、编程复杂、可见性(内存分为工作内存和主内存,这样做主要是为了提高效率)、有序性问题(指令重排)

怎么解决这些问题?

同步机制(volatile、synchronized、原子类、Lock显式锁)

指令重排是什么?为啥要指令重排?

编译器或者处理器对指令执行顺序进行调整,为了提高执行效率。对于重排的指令会遵循以下原则:不影响单线程执行的语义。但是多线程就不能够保证了(会出现可见性问题、有序性问题)。多线程下正常执行语句也不能够保证原子性,所以基于这两种场景,为了保证并发安全性,就出现了锁和其他的一些机制。主要包括volatile,synchronized,显式锁,原子类等

解决指令重排的方法:
Java提供了一些机制来解决指令重排带来的问题:

volatile关键字:通过使用volatile关键字,可以确保变量的读写操作对所有线程都是可见的,并且保证操作的有序性。volatile变量的写操作对任意后续的volatile变量的读操作都是可见的。(内存屏障阻止重排序,https://juejin.cn/post/6901283327160877063)

synchronized关键字:使用synchronized可以确保同一时间只有一个线程可以执行同步代码块,从而保证操作的原子性和有序性。

final关键字:对于final字段,一旦初始化完成,其值就不会被改变。这可以确保在构造函数中对final字段的赋值在构造函数结束后对其他线程是可见的。

原子类:Java提供了一系列的原子类(如AtomicInteger),这些类利用CAS(Compare-And-Swap)操作来保证操作的原子性,从而避免指令重排的问题。

指令重排为啥能够提高执行效率?

这个就是编译器和处理器做的一些优化,主要原则是提高各个硬件(CPU、内存、寄存器)的利用率,减少空闲时间

volatile是啥?有什么用?

这个就得说到JMM,Java内存模型(Java Memory Model,简称JMM)。内存模型把内存分为线程工作内存和主内存。加了volatile修饰的变量就会直接利用本地内存,这样多个线程set操作会直接从线程内存同步到主内存,get操作会直接从主内存同步到线程内存。
JMM的三个核心特性包括:

可见性:确保一个线程对共享变量的修改能够及时地被其他线程观察到。例如,使用volatile关键字修饰的变量,可以保证对该变量的读写操作对所有线程都是即时可见的。

原子性:确保操作是不可分割的,即当一个线程执行原子操作时,其他线程不能插入执行其他操作。Java中的原子操作包括对基本数据类型的赋值操作,以及synchronized块或方法。

有序性:JMM通过happens-before关系来确保操作的有序性。如果一个操作A happens-before 操作B,那么在执行操作B之前,操作A的结果已经对操作B可见,且操作A的执行顺序在操作B之前。

指令重排序破坏了可见性和有序性。
参考:https://www.jianshu.com/p/a67dc1c11088
双层校验锁:https://www.jianshu.com/p/c6a42c543abf

线程的生命周期

https://www.jianshu.com/p/c22ff5cc4a8f
在这里插入图片描述

synchronized底层实现?锁升级?

synchronized 和 lock的区别

https://blog.csdn.net/qq_32907195/article/details/108906260

怎么使用多线程?

继承Thread、实现Runnable接口、实现Callable接口(可以根据FutureTask拿到返回结果)、线程池
参考:
https://zhuanlan.zhihu.com/p/334737925
https://www.cnblogs.com/java1024/p/11950129.html
https://blog.csdn.net/weixin_44797490/article/details/91006241

线程池怎么用?原理?执行流程是咋样的?

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 二层、三层网络基本原理
  • (c语言+数据结构链表)项目:贪吃蛇
  • 【QT基础】创建项目项目代码解释
  • 如何在GitHub上克隆仓库:HTTPS、SSH和GitHub CLI的区别
  • 即插即用!高德西交的PriorDrive:统一的矢量先验地图编码,辅助无图自动驾驶
  • 【嘶吼文化-注册安全分析报告】
  • 使用宝塔部署项目在win上
  • 初探Spring Boot:IntelliJ IDEA2024轻松构建你的第一个SpringBoot应用
  • 【HTML5】html5开篇基础(1)
  • Unity的Text组件中实现输入内容的渐变色效果
  • 基于python+django+vue的在线学习资源推送系统
  • uni-app 聊天界面滚动到消息底部
  • iftop流量监控工具
  • Unborn安装CUDA Toolkit 12.2
  • MySQL:事务的ACID特性隔离级别脏读、不可重复读、幻读、Next-Key锁——场景复现
  • ES6指北【2】—— 箭头函数
  • [ JavaScript ] 数据结构与算法 —— 链表
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • export和import的用法总结
  • HTTP请求重发
  • js对象的深浅拷贝
  • LeetCode算法系列_0891_子序列宽度之和
  • spring boot下thymeleaf全局静态变量配置
  • 初识MongoDB分片
  • 大快搜索数据爬虫技术实例安装教学篇
  • 大型网站性能监测、分析与优化常见问题QA
  • 给初学者:JavaScript 中数组操作注意点
  • 前端
  • 区块链将重新定义世界
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 再谈express与koa的对比
  • 【云吞铺子】性能抖动剖析(二)
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • # Maven错误Error executing Maven
  • #### go map 底层结构 ####
  • #android不同版本废弃api,新api。
  • #php的pecl工具#
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (C++17) optional的使用
  • (二)Linux——Linux常用指令
  • (附源码)计算机毕业设计ssm电影分享网站
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)项目管理杂谈-我所期望的新人
  • (转)一些感悟
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NET gRPC 和RESTful简单对比
  • .net mvc部分视图
  • .Net Redis的秒杀Dome和异步执行
  • .net 托管代码与非托管代码
  • .Net 执行Linux下多行shell命令方法
  • .net对接阿里云CSB服务