【百面成神】多线程基础16问,你能坚持到第几问

在这里插入图片描述

前 言
🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端
☕专栏简介:纯手打总结面试题,自用备用
🌰 文章简介:多线程最基础、重要的16道面试题

文章目录

      • 1.线程池
      • 2.创建线程有哪些方法
      • 3.什么是ABA问题
      • 4.什么是CAS
      • 5.说一说线程的生命周期
      • 6.JMM模型
      • 7.线程死锁问题&线程池满的问题
      • 8.锁升级的原理
      • 9.ThreadLocal
      • 10.volatile关键字的作用
      • 11.synchornized和Lock的区别
      • 12.并发和并行的区别
      • 13.线程和进程的区别
      • 14.start()和run()有什么区别?
      • 15.如何停止一个线程?
      • 16.notify和notifyAll有什么区别?

1.线程池

创建线程需要时间和资源,如果当需要使用一个线程时再创建一个线程,响应时间会变长。可以在程序启动时就创建若干线程来以备响应之需,这些线程由线程池来统一管理。
有以下参数:
核心线程数 corePoolSize
最大线程数 maxPoolSize
存活时间Keepalivetime
单位Unit
工作队列 workqueue
线程工厂 threadFactory
拒绝策略Handler

2.创建线程有哪些方法

继承Thread类
实现Runnable接口(如果要继承其它类,可以实现Runnable接口)
实现Callable接口(和FutureTask结合,有返回值、可以抛出异常)
使用线程池

3.什么是ABA问题

通过多次读取一个值,根据值是否有变化判断数据是否发生改变,但是可能出现值回退的情况。

4.什么是CAS

在引入CAS以前,java通过sychronized加锁,以避免临界资源竞争的问题。但是这是一种悲观锁,获取不到锁的线程会被挂起,上下文切换等也会造成时间损耗,还可能出现优先级较高的线程等待优先级较低的线程释放锁资源的问题。而CAS是一种乐观锁机制,他的全程是CompareAndSet,他他不会立刻加锁,CAS有三个值,内存值,预期值,新值,如果内存值=预期值,就说明临界资源没有被其它线程修改,可以将其更新为新值。

CAS能够从底层硬件级别对于cpu效率进行提升,因此其效率也很高。

但是,CAS可能有ABA问题

5.说一说线程的生命周期

线程刚刚创建时是NEW,开始运行会变成Runnable,如果被IO阻塞或者同步锁阻塞会变成Blocked,如果永久等待状态是Waiting,如果是等待被唤醒是Timed_Waiting,执行完成是Terminated

6.JMM模型

线程之间共享的变量存放在主存中,而每个线程的私有变量存放在各自的本地内存中。

7.线程死锁问题&线程池满的问题

线程A持有独占锁a,并且尝试获取独占锁b,线程B持有独占锁b,并且尝试获取独占锁a。

在工作中会先切换到问题出现的代码版本分支,使用jstack命令做线程dump,并且使用threadIO排查线程死锁问题。曾经遇到一个场景,就是将Lock改为了tryLock,但是没有设置时间参数。最后设置了时间参数解决了问题。

想要避免死锁,可以通过按顺序访问资源来实现。比如线程A,B都是先访问a,再访问b,释放锁的顺序与获取锁的顺序相反。就可以避免死锁。
如果实际可行,也可以一次性获取所有资源。
占用锁资源的线程再去申请锁资源时,如果申请不到锁资源,先释放它现有的锁资源。
还需要注意锁的粒度尽量设置的细点,尽量使用JUC提供并发类,而不要使用手写锁。

8.锁升级的原理

记录threadid,获得偏向锁;再次访问比较线程id,获得轻量级锁,进行一定次数的锁自旋,获得重量级锁。

9.ThreadLocal

每个线程都有一个自己的变量副本,彼此之间隔离,互相不干扰。使用ThreadLocal可以提供比使用sychorinized更简单的一种线程安全机制。在session管理,数据库连接等场景中会有应用。

10.volatile关键字的作用

可以保证修改的可见性,同时避免指令重排序。

11.synchornized和Lock的区别

作用范围:使用syn可以给代码块,方法和变量加锁,而使用lock只可以给代码块加锁
使用方法:使用lock需要手动释放锁
API:使用Lock可以知道是否成功获取锁,但是使用sync却无法做到
实现原理:
Lock的加锁和解锁过程是由java代码配合native方法实现的。
而synchornized是由JVM来直接管理其加锁和解锁的过程。

Synchronized的实现原理是:
先判断markword(对象头中的一个记录字段),是否为可偏向状态,如果是则获取偏向锁(这其实是为了提高单线程下的执行效率,可以理解成为没有锁,直接进入到同步代码块,并在markword中记录下这个线程id),如果由其它线程来抢占锁资源,就会根据当前状态(是否通过CAS算法竞争到锁资源)判断是否要进行锁膨胀,膨胀为轻量级锁。

轻量级锁使用CAS无锁算法。会先检查锁资源对象头的Mark word,看看当前的锁对象是否为无锁状态,如果没有就会先从栈帧中申请一个LockRecord空间。将Markword中的数据进行备份。然后通过CAS算法更新markword,将其指向LockRecord。如果更新成功,则进入同步代码块。如果没有更新成功,检查是否当前线程之前已经获取了锁还没有释放。如果已经获取也可以进入代码块,否则会进行多次锁自旋,需要膨胀为重量级锁。

在java内部每一个对象或类都有一个monitor监视器。重量级锁会通过monitor直接向操作系统申请互斥量。

虚拟机还会自动检查,如果符合条件会进行锁消除(无竞争可能)和锁粗化(循环中使用锁,会自动扩大加锁范围)。

Lock的实现原理:
Lock其实是一个接口,它有ReentrantLock等实现类。
以ReentrantLock为例。它继承了AQS,其底层最后都是调用的AQS的方法来实现的。本质上就是一个双向链表通过不断的进行CAS自旋操作来获取锁。这也是它性能好的原因:避免了线程进入内核态的阻塞状态。

12.并发和并行的区别

并发是为了cpu交替执行不同任务的能力,主要是为了避免cpu资源浪费在等待IO情形,提高cpu的利用率。
并行是在多核环境下,不同cpu执行不同任务的能力,不同核心之间互不干扰,是真正的同时执行。

常见的并发场景有:秒杀活动、股票交易系统等
高并发场景的瓶颈在于:
服务器带宽资源不够、web线程连接数不够、数据库连接上不去。
对应解决并发问题的思路有:
增加网络带宽、DNS域名解析器解析分发到多台服务器
负载均衡:如使用nginx
数据库查询优化,读写分离,分表,合理使用索引等

高并发场景下需要考虑的另一个问题是线程安全问题:
所谓线程安全就是指多线程环境下,同一代码每次执行的结果,都与单线程环境执行的结果一致,而且其它变量的结果,也与预期一致。

13.线程和进程的区别

进程就是一个独立的程序,具有独立的内存空间,比如桌面点开一个IE浏览器网页就是一个进程,点开一个QQ就是另外一个进程。
线程是进程中执行运算的最小单位,一个进程中有多个线程。线程之间既有本地内存,又有共享内存。

进程之间的通信方式有:
管道(半双工、单向流动)、信号量(是一个计数器、常常作为锁机制用来控制多个进程或者线程对共享资源的访问)、消息队列等

线程之间的通信方式有:
锁机制(互斥锁、读写锁等)

补充:可以接着说多线程引入的原因(即并发)

14.start()和run()有什么区别?

Start()内部调用了run()方法。
如果直接调用一个run()方法,不会创建一个新的线程,而是有原来的线程执行该方法。而使用start()方法一定会创建一个新的线程。
调用了start()线程是进入就绪状态,只有获取到了cpu资源才会进入开始状态,才会执行里面调用的run()方法,而不是立即执行。

15.如何停止一个线程?

Java没有提高api停止一个线程,在jdk1.0版本中,提供了suspend,resume,stop等api,但是由于潜在的死锁风险,后续版本中被弃用了。如果想要手工停止一个线程,可以设置一个使用vilotile修饰的布尔变量,在run方法中判断布尔变量的值,来决定是否继续执行run方法。
也可以是用interrupt来实现(推荐:分为有sleep和wait等相应中断的情况[try-catch异常即可]和不含上述方法[while循环增加判断条件即可]的情况)。
参考博客:Java如何停止一个线程_风在哪的博客-CSDN博客

16.notify和notifyAll有什么区别?

当一个线程调用了wait方法以后,它会进入等待池,等待池中的线程不会参与锁资源的竞争。
当调用notify方法时,会随机唤醒一个锁池中线程进入锁池。
当调用notifyAll方法时,则会唤醒所有等待池中的线程,使他们都进入到锁池。
进入到锁池的线程会竞争锁资源,优先级高的线程竞争到锁的可能性较大。
竞争到锁资源以后,线程就会执行synchorinized代码块,执行结束后释放锁,此时其它锁池中的对象会继续下一次竞争。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【百面成神】Redis基础11问,你能坚持到第几问

前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 ☕专栏简介:纯手打总结面试题,自用备用 🌰 文章简介:Redis最基础、重要的11道面试题 文章目录…

AI 未来已至,向量数据库站在新的节点上

“AI 的 iPhone 时刻已经到来。” 在刚刚结束的 NVIDIA GTC Keynote 中,这句话被 NVIDIA CEO 黄仁勋反复提及,长达 1 个多小时的分享中,生成式 AI 相关的内容占据了绝大部分比重。他表示,生成式 AI 的火热能力为企业带来了挑战&a…

2022/3/22 从CV方向角度 —快速解读Nvidia 2023GTC

GTC分享内容和个人看法 3月21号11点,Nvidia开启了GTC主题演讲,这些年英伟达加速库的发展和对AI的投入应用,不难看出掌握GPU加速计算技术的N家肯定是宣扬AI方向的产品和生产工具,下面我将简要汇总下演讲的内容,和从我自…

Java语言-----类与对象的秘密

目录 前言 一、类与对象的介绍 二、类的实例化 三.类与对象的使用方法 3.1对象的初始化 3.2内存显示图 四.this的使用方法 总结 😽个人主页: tq02的博客_CSDN博客-C语言,Java领域博主 🌈理想目标:努力学习,向Java进…

修改linux网卡配置文件的文件名

修改linux网卡配置文件的文件名 查看自己系统中网卡配置文件的文件名 #查看网卡的配置文件名,已经网络的状态 ip a查看系统是否可以使用ifconfig命令 #输入命令 ifconfig #出现以下图片表示ifconfig的命令可用。可能出现的错误:ifconfig command no foun…

第十七天 JavaScript、Vue详细总结

目录 JavaScript、Vue 1. JavaScript常用对象 1.1 Array对象 1.2 String对象 1.3 自定义对象 1.4 JSON 1.5 BOM 1.6 DOM 2. 事件监听 2.1 事件绑定 2.2 常见事件 2.3 案例 3. Vue 3.1 概述 3.2 快速入门 3.3 常用指令 3.4 生命周期 JavaScript、Vue 今日目标&…

为什么说网络安全是风口行业?是IT行业最后的红利?

前言 “没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。 网络安全行业特点 1、就业薪资非常高,涨薪快 2021年猎聘网发布网络安全行业就业薪资行业最高人均33.77万&…

2023年2月用户体验GX评测:国有行及股份行持续领跑,农商行农信社积极探索用户体验提升

易观:2023年2月易观千帆用户体验GX评测显示,国有行及股份制银行继续领跑手机银行用户体验,平安口袋银行、中国工商银行、招商银行稳居AAAAA级;城商行、农商行、农信社重视用户体验,银行下一步重点依然是狠抓用户体验建…

【java基础】Stream流的各种操作

文章目录基本介绍流的创建流的各种常见操作forEach方法filter方法map方法peek方法flatMap方法limit和skip方法distinct方法sorted方法收集结果收集为数组(toArray)收集为集合(collect)收集为Map关于流的一些说明(终结操…

WEB网站服务(一)

1.1 Apache网站服务基础1.1.1Apache简介Apache HTTP Server是开源软件项目的杰出代表,基于标准的HTTP网络协议提供网页浏览服务。Apache服务器可以运行在Linux,UNIX,windows等多种操作系统平台中。1.Apache的起源1995年,Apache服务程序的1.0版…

Linux- 系统随你玩之--玩出花活的命令浏览器-双生姐妹花

文章目录1、背景2、命令浏览器-双生姐妹花2.1、姐妹花简介2.2 、验名正身2.3、常用功能选项3、常用实操3.1、发送请求获取文件3.1.1、抓取页面内容到一个文件中3.1.2、多个文件下载3.1.3、下载ftp文件3.1.4、断点续传3.1.5、上传文件3.1.6、内容输出3.2 、利用curl测试接口3.3 …

毕业设计 基于51单片机自动智能浇花系统设计

基于51单片机自动智能浇花系统设计1、毕业设计选题原则说明(重点)2、项目资料2.1 系统框架2.2 系统功能3、部分电路设计3.1 STC89C52单片机最小系统电路设计3.2 按键电路设计3.3 水泵控制电路设计4、部分代码展示4.1 数码管位选程序4.2 ad0832数据读取程…

HTTPS协议,看这篇就够了

不安全的HTTP 近些年来,越来越多的网站使用 HTTPS 协议进行数据传输,原因在于 HTTPS 相较于 HTTP 能够提供更加安全的服务。 很多浏览器对于使用 HTTP 协议的网站会加上『警告』的标志表示数据传输不安全,而对于使用 HTTPS 协议的网站会加上…

C++11智能指针

目录 一、智能指针的初步认识 1.1 使用场景 1.2 原理 二、std::auto_ptr 2.1 管理权转移 2.2 auto_ptr的模拟实现 三、std::unique_ptr 四、std::shared_ptr 4.1 基础设计 4.2 线程安全问题 4.3 定制删除器 五、std::weak_ptr 六、C11与Boost中智能指针的关系 一、…

脱不下孔乙己的长衫,现代的年轻人该怎么办?

“如果我没读过书,我还可以做别的工作,可我偏偏读过书” “学历本该是我的敲门砖,却成了我脱不下的长衫。” 最近,“脱下孔乙己的长衫”在网上火了。在鲁迅的原著小说中,孔乙己属于知识阶级(长衫客&#xf…

网络安全工具大合集

还是一句话,功夫再高,也怕菜刀首先,恭喜你发现了宝藏。本文章集成了全网优秀的开源攻防武器项目,包含:信息收集工具(自动化利用工具、资产发现工具、目录扫描工具、子域名收集工具、指纹识别工具、端口扫描…

Json数据传递参数

文章目录Json数据传递参数集合参数:Json格式POJO参数:json格式集合参数:json格式RequestBody与RequestParam的区别时间参数的转换Json数据传递参数 第一步 在pom文件中添加相关配置第二步 作用时开启json数据转换成对象postman发送json数据…

CSS 实现六边形柱状图

前言 👏CSS 实现六边形柱状图 速速来Get吧~ 🥇文末分享源代码。记得点赞关注收藏! 1.实现效果 2.实现步骤 定义全局css变量,柱状宽度为–w,最大高度为–h,柱形整体为渐变色,定义上部分颜色为…

【STL三】序列容器——array容器

【STL三】序列容器——array一、array简介二、头文件三、模板类四、成员函数1、迭代器2、元素访问3、容量4、操作五、demo1、容量(不使用迭代器)2、使用迭代器3、元素访问 at()、front()、back()、data()一、array简介 array 容器是 C 11 标准中新增的序…

ChatGPT能否取代程序员?

目录ChatGPT能否取代程序员?ChatGPT和程序员的工作内容和工作方式ChatGPT和程序员的共同点程序员的优势程序员的实力ChatGPT和程序员的关系结论惊喜ChatGPT能否取代程序员? ChatGPT是一种非常普遍的人工智能(AI)系统,…
最新文章