Java并发编程面试题解析
线程基础
1. 解释线程和进程的区别?
进程是操作系统资源分配的基本单位,而线程是CPU调度的基本单位。一个进程可以包含多个线程,它们共享进程的资源,但拥有独立的程序计数器、栈和局部变量等。
2. 如何创建线程?
- 继承 Thread 类
- 实现 Runnable 接口
- 使用线程池
3. Thread 类中 start() 和 run() 方法的区别?
start()
方法用于启动线程,并在新的线程中执行 run()
方法。直接调用 run()
方法只会顺序执行代码,不会创建新的线程。
线程同步
1. 什么是线程安全问题?
当多个线程访问共享资源,并且其中至少有一个线程进行写操作时,就可能发生线程安全问题。
2. Java 中如何实现线程同步?
- synchronized 关键字:可以修饰方法或代码块,保证同一时刻只有一个线程访问同步代码块。
- Lock 接口:提供了比 synchronized 更灵活的锁机制,例如可重入锁、读写锁等。
3. synchronized 和 Lock 的区别?
- synchronized 是 Java 关键字,Lock 是接口。
- synchronized 会自动释放锁,Lock 需要手动释放。
- Lock 提供了更丰富的功能,例如可重入锁、读写锁等。
线程池
1. 为什么要使用线程池?
- 降低资源消耗:重复利用已创建的线程,降低线程创建和销毁的开销。
- 提高响应速度:任务到达时无需等待线程创建即可立即执行。
- 便于管理:线程池可以统一管理线程的生命周期、数量等。
2. ThreadPoolExecutor 的核心参数有哪些?
- corePoolSize:核心线程数
- maximumPoolSize:最大线程数
- keepAliveTime:线程空闲时间
- unit:时间单位
- workQueue:任务队列
- threadFactory:线程工厂
- handler:拒绝策略
3. 常见的线程池拒绝策略有哪些?
- AbortPolicy:抛出 RejectedExecutionException 异常。
- DiscardPolicy:丢弃任务,不做任何处理。
- DiscardOldestPolicy:丢弃队列最旧的任务,然后重试。
- CallerRunsPolicy:由调用线程执行任务。
并发工具
1. CountDownLatch 的作用是什么?
CountDownLatch 可以允许一个或多个线程等待其他线程完成操作后再执行。
2. Semaphore 的作用是什么?
Semaphore 用于控制并发访问的线程数量,可以用于限流等场景。
3. CyclicBarrier 的作用是什么?
CyclicBarrier 可以使多个线程互相等待,直到所有线程都到达某个屏障点后再一起执行。
并发集合
1. ConcurrentHashMap 如何实现线程安全?
ConcurrentHashMap 使用分段锁技术,将数据分成多个段,每个段独立加锁,提高并发性能。
2. CopyOnWriteArrayList 的原理是什么?
CopyOnWriteArrayList 在进行写操作时,先复制一份新的数组,修改完成后再将原数组指针指向新数组。
其他
1. 什么是线程死锁?如何避免死锁?
线程死锁是指多个线程互相等待对方释放资源,导致所有线程都无法继续执行。
避免死锁的方法:
- 避免循环等待资源
- 使用超时机制
- 使用资源分配图进行分析
2. 什么是 volatile 关键字?
volatile 关键字可以保证变量的可见性和有序性,但不能保证原子性。
3. ThreadLocal 的作用是什么?
ThreadLocal 可以为每个线程提供独立的变量副本,避免线程安全问题。
暂无评论