并发编程知识点
一、(面试题)进程和线程的区别
1、线程是进程更小的运行单位,各进程是独立的,而各线程不一定
2、一个进程产生多个线程,线程开销比进程小,但是线程不利于资源的管理和保护,进程相反。
二、线程的状态
创建状态、就绪状态、运行状态、阻塞状态、终止状态
三、启动线程有几种方式
1、继承Thread类
2、实现Runable接口并实现run()方法
3、实现Callable接口并实现call()方法
四、start()方法来运行run()和直接调用run()有什么区别?
start()方法运行run(),是启动一个新的线程来执行run()方法,是真正的多线程,直接调用run()相当于在当前线程调用了一个普通方法,并不是真正的多线程。
总结:调用 start()
方法方可启动线程并使线程进入就绪状态,直接执行 run()
方法的话不会以多线程的方式执行。
五、什么是线程上下文切换
线程上下文切换发送在同一个进程下的两个线程之间,上下文切换是某一线程的时间片用完,该线程被中断,CPU把使用权交给其他线程来执行,若干时间后该线程又继续执行未完成的部分
造成的原因:1、CPU时间片用完 2、垃圾回收导致线程中断 3、有更高优先级的线程需要执行 4、线程自己调用了阻塞方法
造成的后果:影响线程使用性能
解决方案:用CAS算法,实现无锁并发编程,尽可能地减少线程使用,避免创建不需要的线程(可以通过线程池实现)
六、synchronized和ReentrantLock的区别
1、synchronized依赖于jvm,ReentrantLock依赖于API
2、synchronized会自动释放锁,ReentrantLock需要手动开启和释放锁,lock()和unlock()
3、ReentrantLock实现了公平锁和非公平锁,synchronized实现了非公平锁
七、java内存模型JMM
抽象了线程和主内存之间的关系,线程可以把变量保存在本地内存,而不是直接在主内存中对变量进行读写。但是其他线程也可能会使用到这个本地内存的变量值,造成数据不一致的问题。
八、ThreadLocal有什么作用
保证每个线程都有自己的专属本地变量。如果创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的本地副本,可以使用get()和set()来获取值,或者将其值更改为当前线程所存副本的值,从而避免了线程不安全
九、ThreadLocal会发生什么问题,如何解决
会发生内存泄露问题,因为ThreadLocalMap中对key是弱引用,对value是强引用,如果清理了key,key为null,就会被回收,而value不为空,就会一直存在,造成内存泄漏
解决办法就是在用完ThreadLocal方法之后,手动调用remove()方法
十、线程池的七大参数
1、核心线程数
2、最大线程数
3、可存活时间
4、存活时间单位
5、工作队列
6、现场工厂
7、拒绝策略
十一、Atomic类如何实现线程安全
Atomic类使用了CAS+volatile 和 native方法来保证原子操作,从而避免synchronized的高开销,提升执行效率
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现