1 Star 0 Fork 31

moyu3390 / Ebooks_1

forked from Java精选 / Ebooks 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
常见Java并发编程面试题汇总(2021年并发编程面试题大全附答案).md 9.10 KB
一键复制 编辑 原始数据 按行查看 历史

常见Java并发编程面试题汇总(2021年并发编程面试题大全附答案)

全部面试题答案,更新日期:01月30日,直接下载吧!

下载链接:高清500+份面试题资料及电子书,累计 10000+ 页大厂面试题 PDF

Java 并发

题1:什么是线程安全?

如果代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的且其他变量的值也和预期的是一样的,就是线程安全的。

或者也可以理解成一个类或程序所提供的接口对于线程来说是原子操作,多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说不用考虑同步的问题,那就是线程安全的。

题2:Java 中 AQS 核心思想是什么?

AQS核心思想是如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用。

题3:线程池的原理是什么?

线程池状态

线程池和线程一样拥有自己的状态,在ThreadPoolExecutor类中定义了一个volatile变量runState来表示线程池的状态,线程池有四种状态,分别为RUNNING、SHURDOWN、STOP、TERMINATED。

1)线程池创建后处于RUNNING状态。

2)调用shutdown后处于SHUTDOWN状态,线程池不能接受新的任务,会等待缓冲队列的任务完成。

3)调用shutdownNow后处于STOP状态,线程池不能接受新的任务,并尝试终止正在执行的任务。

4)当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态。

线程池原理: 预先启动一些线程,线程无限循环从任务队列中获取一个任务进行执行,直到线程池被关闭。如果某个线程因为执行某个任务发生异常而终止,那么重新创建一个新的线程而已,如此反复。

题4:什么是 Java 内存模型?

Java内存模型定义了java虚拟机在计算机内存中的工作方式。

JMM决定了一个线程对共享变量的写入何时对另一个线程可见。

从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:

线程之间的共享变量存储在主内存中,每一个线程都有一个私有的本地内存,本地内存中存储了该线程以读/写共享变量的副本。

题5:Java 中 volatile 关键字有什么作用?

Java语言提供了弱同步机制,即volatile变量,以确保变量的更新通知其他线程。

volatile变量具备变量可见性、禁止重排序两种特性。

volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。

volatile变量的两种特性:

变量可见性

保证该变量对所有线程可见,这里的可见性指的是当一个线程修改了变量的值,那么新的值对于其他线程是可以立即获取的。

禁止重排序

volatile禁止了指令重排。比sychronized更轻量级的同步锁。在访问volatile 变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。

volatile适合场景:一个变量被多个线程共享,线程直接给这个变量赋值。

当对非volatile 变量进行读写的时候,每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以拷贝到不同CPU cache中。而声明变量是volatile的,JVM 保证了每次读变量都从内存中读,跳过CPU cache这一步。

适用场景

值得说明的是对volatile变量的单次读/写操作可以保证原子性的,如long和double类型变量,但是并不能保证“i++”这种操作的原子性,因为本质上i++是读、写两次操作。在某些场景下可以代替Synchronized。但是,volatile的不能完全取代Synchronized的位置,只有在一些特殊的场景下,才能适用volatile。

总体来说,需要必须同时满足下面两个条件时才能保证并发环境的线程安全:

1)对变量的写操作不依赖于当前值(比如 “i++”),或者说是单纯的变量赋值(boolean flag = true)。

2)该变量没有包含在具有其他变量的不变式中,也就是说,不同的volatile变量之间,不 能互相依赖。只有在状态真正独立于程序内其他内容时才能使用volatile。

题6:CAS 有什么缺点?

1、CAS容易造成ABA问题。

一个线程a将数值改成了b,接着又改成了a,此时CAS认为是没有变化,其实是已经变化过了,而这个问题的解决方案可以使用版本号标识,每操作一次version加1。在JDK1.5版本中,已经提供了AtomicStampedReference来解决问题。

2、CAS造成CPU利用率增加。之前说过了CAS里面是一个循环判断的过程,如果线程一直没有获取到状态,cpu资源会一直被占用。

题7:Java 支持协程吗?

Java 官方目前是还没推出协程。

目前可用性比较高的有Quasar和ea-async两个第三方库,都是通过byte code Instrument,把编译后同步程序class文件修改为异步的操作。

题8:Java 中 ConcurrentHashMap 并发度是什么?

ConcurrentHashMap把实际map划分成若干部分来实现它的可扩展性和线程安全。这种划分是使用并发度获得的,它是ConcurrentHashMap类构造函数的一个可选参数,默认值为16,这样在多线程情况下就能避免争用。

在JDK1.8版本之后,ConcurrentHashMap摒弃了Segment(锁段)的概念,而是启用了一种全新的方式实现,利用CAS算法。同时加入了更多的辅助变量来提高并发度,具体内容可以关注微信公众号“Java精选”,源码解析。

题9:Thread 类中 yield() 方法有什么作用?

yield()方法使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。

当前线程到了就绪状态,至于哪个线程会从就绪状态变成执行状态,有可能是当前线程,也可能是其他线程,这就看系统的分配了。

题10:为什么 wait() 和 notify() 方法要在同步块中调用?

一方面是Java API强制要求这样做,如果不这么做的话,代码就会抛出IllegalMonitorStateException异常。

另外一方面是为了避免wait()和notify()方法之间产生竞争条件。

题11:notify()-和-notifyall()-方法有什么区别

题12:线程优先级是什么

题13:sleep()-方法和-wait()-方法有什么区别和共同点

题14:java-中如何获取线程堆栈

题15:java-中-cyclibarriar-和-countdownlatch-有什么区别

题16:什么是-callable-和-future

题17:java-中同步集合与并发集合有什么区别

题18:什么是futuretask

题19:java-中-semaphore-是什么

题20:创建线程池的有几种方式

题21:如何避免线程死锁

题22:锁优化的方法有哪些

题23:java-中用到的线程调度算法是什么

题24:程序计数器为什么是私有的

题25:什么是-aba-问题

大厂面试题

大厂面试题

大厂面试题

Java
1
https://gitee.com/moyu3390/ebooks_1.git
git@gitee.com:moyu3390/ebooks_1.git
moyu3390
ebooks_1
Ebooks_1
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891