多线程面试题
多线程有几种实现方式?
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口通过FutureTask包装器(同时实现了Future和Runnable接口)来创建Thread线程(创建FutureTask类实例,将实现了Callable的类放入FutureTask的构造方法,然后再将FutureTask的实例放入Thread的构造器,然后用Thread实例调用start())通过线程池创建线程,使用线程池接口ExecutorService结合Callable、Future实现有返回结果的多线程。
线程池
Runnable和 Callable有什么区别?
Runnable没有返回值,Callable可以拿到有返回值,Callable可以看作是 Runnable的补充。
Callable的返回值如果你在泛型中指定,返回值就是你指定的,如果你没有指定,默认是object
线程的状态?
初始化 就绪(实际不存在) 运行 阻塞 (计时等待 超时等待 同步阻塞) 终止
notify()和 notifyAll()有什么区别?
notifyAll()会唤醒所有的线程,notify()之后唤醒一个线程。
notifyAll() 调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。
notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制。
run() 和 start() 区别?
start() 用于启动线程 只能调用一次
run() 用于执行线程的任务代码 可以多次调用
并发编程的三个重要特征
原子性 可见性 有序性
volatile关键字
volatile 是变量修饰符,可以保证内存可见性,有序性,不保证原子性,不会造成线程阻塞
synchronized 和 volatile 的区别是什么?
volatile 是变量(类变量和实例变量)修饰符;synchronized 是修饰方法、代码段。
volatile 仅能实现变量的修改可见性,有序性,不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性,有序性。
volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。
CAS:Compare and Swap
CAS 是一种原子操作,它包含三个主要参数:
1. 内存值(Memory Value):需要更新的变量的当前值。
2. 预期值(Expected Value):线程期望内存值为的值。
3. 新值(New Value):如果预期值与内存值一致,则将内存值更新为这个新值。
CAS 的操作逻辑如下:
• 如果内存值等于预期值,则将内存值更新为新值,并返回 true 。
• 如果内存值不等于预期值,则不进行更新,并返回 false 。
CAS 的优点
无锁机制:CAS 是一种无锁机制,不依赖传统的互斥锁(如 synchronized 或 ReentrantLock )。它通过原子操作避免了线程之间的直接竞争,减少了锁的开销。
高并发性能:在高并发场景下,CAS 可以显著提高性能,因为它避免了线程阻塞和上下文切换的开销。
避免死锁:由于 CAS 不涉及锁的获取和释放,因此不会出现死锁问题。
synchronized 和 Lock 有什么区别
synchronized 可以给类、方法、代码块加锁;而 lock 只能给代码块加锁。
synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,机制上不会造成死锁;而 lock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁
CAS/乐观锁在开发项目中的实践?
订单表和流水表,为了防止并发问题,就会加入CAS的校验过程,保证了线程的安全问题,但是看场景使用,并不是适用所有场景,优缺点都很明显.ABA的问题的话,加标志位,是使用version字段做的,之前我们只查询值是否匹配,现在我们要一同查出version字段也是否匹配.
posted on 2025-12-19 16:15 lubingliang 阅读(0) 评论(0) 收藏 举报
浙公网安备 33010602011771号