Java并发编程常见面试题解析
线程基础
- 解释线程和进程的区别?
进程是操作系统资源分配的基本单位,而线程是CPU调度的基本单位。一个进程可以包含多个线程,它们共享进程的资源,但拥有独立的程序计数器、堆栈和局部变量等。
- 描述线程的生命周期及其状态转换?
线程的生命周期包括新建、就绪、运行、阻塞和终止五种状态。
- 新建:线程对象已创建但尚未启动。
- 就绪:线程具备运行条件,等待CPU调度。
- 运行:线程获得CPU资源正在执行。
- 阻塞:线程因某种原因暂停执行,例如等待IO或获取锁。
- 终止:线程执行完毕或异常退出。
- 如何创建和启动线程?
可以通过继承Thread类或实现Runnable接口来创建线程,并调用start()方法启动线程。
线程同步
- 什么是线程安全问题?
当多个线程同时访问共享资源,且至少有一个线程进行写操作时,就可能出现数据不一致的问题,这就是线程安全问题。
- 解释 synchronized 关键字的作用?
synchronized关键字用于实现线程同步,它可以保证同一时刻只有一个线程执行被修饰的代码块或方法,从而避免数据竞争。
- volatile 关键字有什么作用?
volatile关键字保证了变量的可见性和禁止指令重排序,确保线程读取到的变量值是最新的。
-
介绍几种常见的线程安全集合类?
-
Vector、Hashtable:早期版本提供的线程安全集合类,效率较低。
- ConcurrentHashMap、CopyOnWriteArrayList:基于更细粒度锁机制实现的线程安全集合类,效率更高。
线程池
- 为什么要使用线程池?
线程池可以减少线程创建和销毁的开销,提高系统资源利用率,并方便线程管理。
-
解释线程池的核心参数?
-
corePoolSize:核心线程数。
- maximumPoolSize:最大线程数。
- keepAliveTime:非核心线程闲置超时时间。
- workQueue:任务队列。
- threadFactory:线程工厂,用于创建线程。
-
handler:拒绝策略,当线程池已满且任务队列也满时如何处理新任务。
-
介绍几种常见的线程池拒绝策略?
-
AbortPolicy:直接抛出RejectedExecutionException异常。
- DiscardPolicy:丢弃新任务。
- DiscardOldestPolicy:丢弃队列中最老的任务,然后重试。
- CallerRunsPolicy:由调用线程执行任务。
并发工具类
- CountDownLatch 的作用是什么?
CountDownLatch允许一个或多个线程等待其他线程完成操作后再继续执行。
- CyclicBarrier 和 CountDownLatch 的区别?
CountDownLatch 用于一次性的计数控制,而 CyclicBarrier 可以重复使用,用于线程间相互等待。
- Semaphore 的作用是什么?
Semaphore 用于控制并发线程数,可以通过 permits 数量限制对资源的访问。
- Exchanger 的作用是什么?
Exchanger 允许两个线程在同步点交换数据。
其他
- ThreadLocal 的作用是什么?
ThreadLocal 为每个线程提供独立的变量副本,避免线程间数据共享问题。
- 什么是死锁?如何避免死锁?
当两个或多个线程互相持有对方需要的资源,导致程序无法继续执行,这就是死锁。避免死锁的方法包括:
- 避免循环等待资源。
- 使用超时机制获取资源。
- 使用资源分配图进行分析。
总结
并发编程是Java开发中的重要内容,掌握线程基础、同步机制、线程池、并发工具类等知识点是应对面试的关键。
暂无评论