面试总结(三)

news2024/11/24 16:40:06

1.进程和线程的区别

  • 根本区别:进程是操作系统分配资源的最小单位;线程是CPU调度的最小单位
  • 所属关系:一个进程包含了多个线程,至少拥有一个主线程;线程所属于进程
  • 开销不同:进程的创建,销毁,切换所需要的资源远远大于线程
  • 拥有的资源:每一个进程都拥有自己的内存和资源;线程不会独立的拥有这些资源,而是共享所属进程申请来的资源
  • CPU利用率不同:进程的利用率比较低,因为上下文切换开销较大,而线程的CPU;利用率比较高,上下文切换速度比较快
  • 控制力和影响力不同:子进程无法影响父进程,而子线程可以影响父线程,如果子线程发生异常会影响其所在的进程和子线程。

2.线程安全是什么

通俗的来讲,线程安全就是在多线程环境下,运行的结果符合我们的预期(即与单线程运行的结果相同),此时我们就说是线程安全

3.为什么会出现线程不安全问题呢

  • 线程的抢占式执行
  • 多个线程同时修改同一个变量
  • 未保证操作的原子性内存可见性
  • 指令重排序

4.Synchronized和volatile

1.volatile

volatile 解决的是内存可见性问题

1.1 volatile 原理

volatile原理是基于CPU内存屏障指令实现的

1.2 volatile 修饰的变量可见性

volatile是变量修饰符,其修饰的变量具有内存可见性

一般情况下线程在执行时,Java中为了加快程序的运行效率,会先把主存数据拷贝到线程本地(寄存器或是CPU缓存),操作完成后再把结果从线程本地缓存刷新到主存中,这样就会导致修改后放入变量结果同步到主存中需要一个过程,而此时另外的线程看到的还是修改之前的变量值,这样就会导致不一致

为了解决上述多线程中内存可见的问题,引入了 volatile 关键字,那么它为什么可以解决内存可见性问题呢?

答案: volatile 它会使得所有对 volatile 变量的读写都会直接读写主存,而不是先读写线程本地缓存,这样就保证了变量的内存可见性

1.3 volatile 禁止指令重排 

volatile可以禁止进行指令重排

指令重排: 处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证各个语句的执行顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。指令重排序不会影响单个线程的执行,但是会影响到线程并发执行时的正确性

线程执行到volatile修饰变量的读写操作时,其他线程对这个变量的操作肯定已经完成了,且结果已经同步到了主存中,即对其他的线程可见,本线程再对该变量操作完全没有问题的

1.4 volatile 使用范围

volatile关键字仅能实现对原始变量(如boolen、 short 、int 、long等)操作的原子性,不能保证复合操作的原子性,比如 i++

i++,实际上是由三个原子操作组成:read i; inc; write i,假如多个线程同时执行i++,volatile只能保证他们操作的i是同一块内存,但不能保证i结果的正确性,原因如下:

比如有两个线程A和B对volatile修饰的i进行i++操作,i的初始值是0,A线程执行i++时刚读取了i的值0,就切换到B线程了,B线程(从内存中)读取i的值也为0,然后就切换到A线程继续执行i++操作,完成后i就为1了,接着切换到B线程,因为之前已经读取过了,所以继续执行i++操作,最后的结果i就为1了,A和B线程同步到主存中的i的值都是1

1.5 volatile 使用场景

1、 对变量的写入操作不依赖变量的当前值,或者只有单个线程更新变量的值

2、 该变量没有包含在具有其他变量的不变式中

2.synchronized

  • synchronized 既解决了内存可见性问题,又解决了执行顺序问题
  • synchronized 可以修饰代码块或方法,既可以保证可见性,又能够保证原子性

2.1 synchronized 原理

synchronized 是基于 monitor 实现的

2.2 synchronized 修饰的代码块或方法保证内存可见性

通过synchronized或者Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存中

2.3 synchronized 修饰的代码块或方法保证原子性

线程要么不执行(线程没有获取到对象锁),线程要么执行到底(线程获取到了对象锁),直到执行完释放锁

2.4 synchronized 使用范围

synchronized 不仅能修饰代码块,还可以修饰方法

2.5 synchronized 使用场景

需要控制多线程访问的方法或者更新的变量

3.volatile 和 synchronized 异同点


3.1 相同点

volatile 和 synchronized 都保证了内存可见性

3.2 不同点

  • volatile仅能使用在变量级别,synchronized则可以使用在变量、方法、和类级别的
  • volatile仅能实现变量的修改可见性,不能保证原子性,而synchronized则可以保证变量的修改可见性和原子性
  • volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞
  • volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化
  • 由于 4 中的区别,在某些情况下 volatile 的性能优于 synchronized

5.线程的状态

  • NEW:表示创建了一个线程,但是还没有开始执行
  • RUNNABLE:线程的状态是运行 + 就绪状态,在CPU开始执行了
  • TERMINATED:线程在CPU上运行结束,系统线程已经销毁,但是Java对象还没有回收
  • TIMED_WAITING:带超时时间的等待状态,wait(time),sleep(time),join(time),过时不候
  • WAITING:没有指定超时时间的等待状态,一直等待
  • BLOCK:加了Synchronized之后,其他线程在等待竞争锁资源时的等待状态

6.wait(),sleep(),yield(),join()的区别

  1. wait():属于Object类的方法,wait()过程中会释放锁,只有notify才可以唤醒线程。wait使用时必须获取锁对象,也就是说必须要搭配synchronized来使用。如果没有synchronized,则会报错
  2. sleep():属于Thread类的方法,sleep过程中不会释放锁,一直占着锁资源,只会线程阻塞,让出CPU给其他线程执行,但是他的监控状态依然保持,当指定的时间到了之后又会回复运行的状态,可中断
  3. join():属于Thread类的方法,等待调用join()的线程结束之后,程序再继续执行一般用于等待异步线程执行完结果之后才能继续运行的场景
  4. yield():属于Thread类的方法,和sleep一样,都是暂停当前执行的线程对象,不会释放锁资源,和sleep不同的是,yield方法不会让线程进入阻塞状态,而是让线程重新回到就绪状态等待CPU调度。

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

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

相关文章

交流电气装置防雷接地电阻测量的方案

一、目的 为了保证交流电气装置的安全运行和防止雷电对其造成损坏,需要定期检测其接地装置的接地电阻,评估其接地效果和防雷性能。 二、原理 地凯科技认为:接地电阻是指接地装置与大地之间的电阻,它反映了接地装置与大地的接触…

【104协议】【光伏电站】电站系统中的104协议学习

文章目录 104协议学习I帧S帧U帧ASDU总结:关于各类帧的通俗描述建立流程详细分析 104协议学习 起始一个apdu的总长度不会超过255个字节; 在协议中的第二个字节会记录本apdu的长度,但是这个记录的长度数是除开前面两个字节之外的长读数&#xf…

【C++】开源:Linux端V4L2视频设备库

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍Linux端V4L2视频设备库。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下…

笨办法学python3进阶篇pdf,笨办法学python3pdf完整版

大家好,小编来为大家解答以下问题,笨办法学python 3电子书下载,笨办法学python3pdf完整版,今天让我们一起来看看吧! 1、笨方法学python习题43 按照你说的 Map是一个类,scene_map是一老胡镇个类实例 scene_…

Scratch 详解 流畅光线追踪(盲区)引擎:角度 + 一次函数 + 区域判断

【提示1】本文将全程使用原版积木实现这一功能,请不要在评论区发送扩展中有相应积木。若喜欢使用扩展,可以自行将本文介绍的方法用扩展积木替代。 【提示2】本文中代码里出现的所有最后带*号的变量,均为私有变量! 正文 近日&…

C数据结构——无向图(邻接矩阵方式) 创建与基本使用

源码注释 // // Created by Lenovo on 2022-05-13-上午 9:06. // 作者&#xff1a;小象 // 版本&#xff1a;1.0 //#include <stdio.h> #include <malloc.h>#define MAXSIZE 1000 // BFS队列可能达到的最大长度 #define MAX_AMVNUMS 100 // 最大顶点数typedef enu…

用SpringBoot实现post和get请求(多图)

用SpringBoot实现post和get请求&#xff08;多图&#xff09; 用SpringBoot实现post和get请求创建SpringBoot工程创建controller验证FAQ创建项目后依赖报错Project org.springframework.boot:spring-boot-starter-parent:3.1.2.RELEASE not found more 用SpringBoot实现post和g…

AQS构建锁和同步器的框架

1.概述 AQS全称AbstractQueuedSynchronizer&#xff0c;此类在java.util.concurrent.locks包下面&#xff0c;是一个构建锁和同步器的框架&#xff0c;比如ReentrantLock就是基于AQS来实现的。 2.AQS实现原理 AQS内部有一个由volatile修饰(保证其可见性)的变量state&#xf…

PDF文件忘记密码,怎么办?

PDF文件设置密码分为打开密码和限制密码&#xff0c;忘记了密码分别如何解密PDF密码&#xff1f; 如果是限制编辑密码忘记了&#xff0c;我们可以试着将PDF文件转换成其他格式来避开限制编辑&#xff0c;然后重新将文件转换回PDF格式就可以了。 如果因为转换之后导致文件格式…

Tuxera NTFS2023Mac强大的Mac读写工具

Mac用户在使用NTFS格式移动硬盘时&#xff0c;会遇到无法写入硬盘的情况。要想解决无法写入的问题&#xff0c;很多人选择使用Mac读写软件。面对市面上“众多”的读写硬盘软件&#xff0c;用户应该怎么选择呢&#xff1f;初次接触移动硬盘的伙伴可能不知道移动硬盘怎么和电脑连…

RabbitMQ 教程 | 第6章 RabbitMQ 配置

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

科大讯飞 - 基于论文摘要的文本分类与关键词抽取挑战赛(DataWhale-Camp)

文章目录 1、赛题信息2、解决方案2.1 飞桨Baseline&#xff08;提供代码&#xff09;2.2 Bert和调参2.3 chatGLMlora大模型 3、关于DataWhale-NLP 1、赛题信息 提交地址&#xff1a;https://challenge.xfyun.cn/topic/info?typeabstract-of-the-paper&chymfk4uU 项目题目…

我的会议(会议通知)

前言: 我们在实现了发布会议功能&#xff0c;我的会议功能的基础上&#xff0c;继续来实现会议通知的功能。 4.1实现的特色功能&#xff1a; 当有会议要参加时&#xff0c;通过查询会议通知可以知道会议的内容&#xff0c;以及当前会议状态&#xff08;未读&#xff09; 4.2思路…

在Linux中怎么查找文件

2023年8月1日&#xff0c;周二上午 目录 Linux的四种搜索命令find简要说明举例说明拓展阅读locate 简要说明举例说明whereis简要说明举例说明which简要说明举例说明 Linux的四种搜索命令 findlocate&#xff08;不一定内置有&#xff0c;可能要下载mlocate包&#xff09;wher…

【概念理解】HAL库的滴答定时器HAL_Delay()函数的实现原理

来源&#xff1a;bilibili视频 这里写目录标题 概述一、寄存器部分1. 控制和状态寄存器(STK_CTRL)2. 加载值寄存器&#xff08;STK_LOAD&#xff09;3.当前值寄存器&#xff08;STK_VAL&#xff09; 二、代码部分hal_delay()1. hal_initTick()滴答定时器的初始化2. 将七万二传…

Redis 客户端有哪些?

文章目录 JedisLettuceRedisson最佳实践 - 到底用哪个&#xff1f; Redis 最常见的 Java 客户端有两个&#xff0c;Jedis 和 Lettuce&#xff0c;高级客户端有 Redisson&#xff0c;见下图&#xff08;图源 Clients | Redis&#xff09; Jedis Github地址&#xff1a;redis/j…

Windows下安装Hive(包安装成功)

Windows下安装Hive Hive与Hadoop的版本选择很关键&#xff0c;千万不能选错&#xff0c;否则各种报错。一、Hive下载1.1、官网下载Hive1.2、网盘下载Hive 二、解压安装包&#xff0c;配置Hive环境变量2.1、环境变量新增&#xff1a;HIVE_HOME2.2、修改Path环境变量&#xff0c;…

Oracle免费在线编程:Oracle APEX

前提&#xff1a; 注意&#xff1a;你要有个梯子才能更稳定的访问。 不需要安装Oracle&#xff0c;但是需要注册。&#xff08;还算方便的&#xff09; 注册&登录过程 进入Oracle APEX官网&#xff0c;我们选择免费的APEX工作区即可&#xff0c;点击“免费注册”。在注册…

基于H5或者微信小程序开发GIS地图实战全套代码

1 下面有一定基础的可以不看 (1)第一篇请看 微信小程序开发天地图 (2)第二篇请看 http://GeoServer+PostgreSQL+PostGIS+Tomcat+QGIS一整套相关 (3)第三篇请看 有国产化需求的 (4)第四篇请看 支持国家EPSG:4490 2 vue+openlayers实例代码

ThreadLocal原理

ThreadLocal原理 ThreadLocal对象new出来存放到堆中&#xff0c;ThreadLocal引用是存放在栈里 Thread 类有个 ThreadLocalMap 成员变量&#xff0c;Map的key是Threadlocal 对象&#xff0c;value是你要存放的线程局部变量。 public void set(T value) {//获取当前线程Thread&…