面试(03)————多线程

目录

一、线程和进程的区别?

二、并行和并发的区别?

三、线程创建的方式有哪些?

3.1、继承Thread类

3.2、实现Runnable接口

3.3、实现Callable接口

3.4、线程池

四、Runnable和Callable的区别?

五、在启动线程的时候,可以使用run方法吗?run()和start()有什么区别?

六、线程包含了哪些状态?状态之间是如何变化的?

七、新建T1、T2、T3三个线程,如何保证它们按顺序执行?

八、notify和notifyAll有什么区别?

九、Java中wait方法和sleep方法有什么不同?

十、如何停止一个正在运行的线程?

十一、synchronized关键字的底层原理

十二、Monitor实现的锁属于重量级锁。你了解过锁升级吗?

十三、谈谈JMM(Java内存模型)

十四、CAS

十五、乐观锁和悲观锁

十六:谈谈你对volatile的理解

十七、AQS

十八、ReentrantLock的实现原理

十九、synchronized和Lock有什么区别?

二十、死锁产生的条件?

二十一、如何进行死锁诊断?

二十二、ConcurrentHashMap

二十三、Java程序中怎么保证多线程的执行安全?(导致并发程序出现问题的根本原因是什么)

二十四、线程池的核心参数(线程池的执行原理)

二十五、线程池中有哪些常见的阻塞队列

二十六、如何确定核心线程数

二十七、线程池的种类有哪些

二十八、为什么不建议Executors创建线程池


一、线程和进程的区别?

进程:

  • 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理IO的
  • 当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。
  • 进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如记事本、画图、浏览器等),也有的程序只能启动一个实例进程(例如网易云音乐、360安全卫士等)

线程:

一个进程之内可以分为一到多个线程。

一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给CPU执行

Java中,线程作为最小调度单位,进程作为资源分配的最小单位。在windows中进程是不活动的,只是作为线程的容器

二、并行和并发的区别?

并发是指系统具有处理多个任务的能力,但这并不意味着这些任务同时执行。在单核CPU的环境下,CPU通过在任务之间迅速切换(上下文切换),给人一种似乎是同时处理多个任务的错觉。因此,并发关注的是多个任务的启动、执行和完成的顺序,使得多个任务看似在"同时"执行,实际上从宏观角度是的,但从微观角度看,这些任务可能并没有在同一时刻被处理。

并行处理是指多个处理器或多核处理器同时处理多个任务。在这种情况下,任务确实是在同一时刻被执行。并行执行的目的是通过同时使用多个计算资源来减少程序的执行时间。它适用于那些可以被分解为可以独立执行的多个子任务的问题。

简单来说:

三、线程创建的方式有哪些?

3.1、继承Thread类

3.2、实现Runnable接口

3.3、实现Callable接口

3.4、线程池

四、Runnable和Callable的区别?

五、在启动线程的时候,可以使用run方法吗?run()和start()有什么区别?

六、线程包含了哪些状态?状态之间是如何变化的?

线程的状态可以参考JDK中的Thread类中的枚举State

七、新建T1、T2、T3三个线程,如何保证它们按顺序执行?

八、notify和notifyAll有什么区别?

九、Java中wait方法和sleep方法有什么不同?

十、如何停止一个正在运行的线程?

十一、synchronized关键字的底层原理

十二、Monitor实现的锁属于重量级锁。你了解过锁升级吗?

十三、谈谈JMM(Java内存模型)

十四、CAS

CAS全程是:Compare And Swap(比较再交换),它体现的一种乐观锁的思想,在无锁情况下保证线程操作共享数据的原子性。

在JUC包下实现的很多类都用到了CAS操作

比如: AbstractQueuedSynchronizer(AQS框架)、AtomicXXX类

CAS数据交换流程:

一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当旧的预期值A和内存值V相同时,将内存值修改为B并返回ture,否则什么都不做,并返回false。如果CAS操作失败,通过自旋的方式等待并再次尝试,直到成功

十五、乐观锁和悲观锁

乐观锁:

它假设不会产生冲突,先去尝试执行某项操作,失败了再进行其他处理(一般都是不断循环重试)。这种锁不会阻断其他线程,也不涉及上下文切换,性能开销小。代表实现是:CAS

悲观锁:

它假设一定会发生冲突,因此获取到锁之后会阻塞其他等待线程。这样做的好处是简单安全,但是挂起线程和回复线程都需要转入内核态进行,这样做的话会带来很大的性能开销。悲观锁的代表是synchronized。然而在真实环境中,大部分时候都不会产生冲突。

十六:谈谈你对volatile的理解

总结:

十七、AQS

全称是 AbstractQueueSynchronizer,即抽象队列同步器。它是构建锁或者其他同步组件的基础框架

AQS基本工作机制:

在AQS内部有一个属性state,这个state就相当于一个资源,默认是0(无锁状态),如果队列中的有一个线程修改成功了state为1,则当前线程就相当于获取了资源

QS内部维护了一个先进先出的双向队列,队列中存储的排队的线程

在对state修改的时候使用的CAS操作,保证多个线程修改的情况下原子性

AQS可以是公平锁,也可以是非公平锁

公平锁是指各个线程在加锁前先检查有无排队的队列,按排队顺序取获得锁。(新的线程到队列中等待,只让队列中的head线程获取锁,是公平锁)

非公平锁是指线程加锁前不考虑排队问题,直接尝试获取锁,获取不到再去队尾排队。值得注意的是,在AQS的实现中,一旦线程进入排队队列,即使是非公平锁,线程也需要乖乖排队(新的线程与队列中的线程共同来抢资源,是非公平锁)

十八、ReentrantLock的实现原理

ReentrantLock 内部有两个内部类,分别是 FairSync 和 NonFairSync,对应公平锁和非公平锁。他们都继承自 Sync。Sync 又继承自AQS。

总结:

十九、synchronized和Lock有什么区别?

二十、死锁产生的条件?

二十一、如何进行死锁诊断?

二十二、ConcurrentHashMap

总结:

二十三、Java程序中怎么保证多线程的执行安全?(导致并发程序出现问题的根本原因是什么)

volatile加在共享变量上!!

总结:

二十四、线程池的核心参数(线程池的执行原理)

二十五、线程池中有哪些常见的阻塞队列

二十六、如何确定核心线程数

二十七、线程池的种类有哪些

总结:

二十八、为什么不建议Executors创建线程池

相关推荐
Lee川14 小时前
优雅进化的JavaScript:从ES6+新特性看现代前端开发范式
javascript·面试
Lee川18 小时前
从异步迷雾到优雅流程:JavaScript异步编程与内存管理的现代化之旅
javascript·面试
晴殇i20 小时前
揭秘JavaScript中那些“不冒泡”的DOM事件
前端·javascript·面试
绝无仅有20 小时前
Redis过期删除与内存淘汰策略详解
后端·面试·架构
绝无仅有20 小时前
Redis大Key问题排查与解决方案全解析
后端·面试·架构
AAA梅狸猫21 小时前
Looper.loop() 循环机制
面试
AAA梅狸猫21 小时前
Handler基本概念
面试
Wect1 天前
浏览器缓存机制
前端·面试·浏览器
掘金安东尼1 天前
Fun with TypeScript Generics:玩转 TS 泛型
前端·javascript·面试
掘金安东尼1 天前
Next.js 企业级落地
前端·javascript·面试