31. Java中的CAS操作是什么?它有什么优缺点?
答案:
CAS(Compare And Swap)是一种乐观锁技术,用于实现多线程环境下的原子操作。它通过比较当前值与期望值是否相等来确定是否执行更新操作。优点是避免了使用锁带来的性能开销,缺点是可能存在ABA问题(解决方法是使用版本号等方式)和自旋操作可能造成CPU资源浪费。
32. 什么是Java中的线程安全?如何保证线程安全?
答案:
线程安全是指多个线程访问某个对象或变量时,不会出现不正确的结果。可以通过以下方式保证线程安全:
- 使用同步方法(synchronized)或同步代码块来保护共享资源。
- 使用并发集合类,如
ConcurrentHashMap
、CopyOnWriteArrayList
等,它们内部实现了线程安全机制。 - 使用原子类,如
AtomicInteger
、AtomicBoolean
等,通过CAS操作保证单个变量的原子性操作。 - 使用不可变对象,确保对象状态不可修改,从而避免线程安全问题。
33. 解释一下Java中的死锁现象。如何避免死锁?
答案:
死锁是指两个或多个线程互相持有对方需要的资源,并且都在等待对方释放资源,从而导致所有线程都无法继续执行的状态。要避免死锁,可以采取以下策略:
- 避免一个线程同时获取多个锁。
- 避免嵌套锁的获取。
- 使用
tryLock()
方法来获取锁,避免无限期等待。 - 使用
Thread.join()
时注意线程加入的顺序,避免循环依赖。 - 使用锁的顺序来规避死锁,即所有线程都按照相同的顺序获取锁。
34. 什么是Java中的线程状态?列举几种常见的线程状态。
答案:
Java中的线程状态是指线程在其生命周期中可能处于的不同状态。常见的线程状态包括:
- NEW:线程被创建但还未启动。
- RUNNABLE:线程正在Java虚拟机中执行,可能正在运行也可能处于就绪状态等待调度。
- BLOCKED:线程被阻塞,等待获取一个同步锁。
- WAITING:线程无限期地等待另一个线程执行特定操作,直到被其他线程中断或通知。
- TIMED_WAITING:线程等待另一个线程执行特定操作,但只等待一段时间。
- TERMINATED:线程已经执行完毕。
35. 什么是Java中的线程组(ThreadGroup)?它有什么作用?
答案:
线程组(ThreadGroup)是Java中用来管理线程的一种结构,它可以包含一组线程和子线程组。线程组的主要作用包括:
- 组织管理线程:可以将多个线程归为一个组,便于集中管理。
- 统一设定线程属性:如设置线程优先级、设置守护线程等。
- 统一处理未捕获异常:可以通过重写
uncaughtException()
方法来统一处理线程组内所有线程抛出的未捕获异常。
36. Java中的守护线程是什么?如何创建守护线程?
答案:
守护线程(Daemon Thread)是一种在后台提供服务的线程,当所有非守护线程结束时,守护线程会自动销毁。可以通过以下方式创建守护线程:
- 使用
setDaemon(true)
方法将线程设置为守护线程。 - 必须在启动线程之前设置守护标志,否则会抛出
IllegalThreadStateException
异常。 - 守护线程通常用于执行后台任务或提供辅助服务,如垃圾回收线程就是一个典型的守护线程。
37. 解释一下Java中的内存模型(Java Memory Model,JMM)。它的作用是什么?
答案:
Java内存模型定义了Java虚拟机如何在主内存和工作内存中存储数据、以及线程如何与主内存中的变量进行交互。主要作用包括:
- 确定一个线程如何与主内存中的变量进行同步访问。
- 确定何时以及如何将变量的值从工作内存同步回主内存。
- 确定何时可以使用锁来实现线程之间的同步。
38. Java中的volatile关键字是什么?它有什么作用?
答案:volatile
是Java中的关键字,用于修饰变量,保证其在多线程环境下的可见性。具体作用包括:
- 禁止指令重排序优化,保证指令按照代码顺序执行。
- 提供了一种轻量级的同步机制,适用于变量的写操作不依赖于当前值的场景。
- 当一个变量定义为
volatile
后,每个线程都会读取该变量的最新值,而不是缓存中的值,从而避免了线程之间的数据不一致问题。
39. 什么是Java中的可重入锁(Reentrant Lock)?它有什么特点?
答案:
可重入锁(Reentrant Lock)是Java中的一种锁机制,与synchronized
关键字类似,但具有更灵活的操作方式和更丰富的功能。它的特点包括:
- 支持公平锁和非公平锁。
- 提供了可中断的锁获取、定时锁获取等特性。
- 支持多个条件变量,可以通过
Condition
接口实现更精细的线程通信。 - 具有可重入性,同一线程可以多次获取同一把锁,不会死锁。
40. Java中的读写锁(ReadWriteLock)是什么?它有什么作用?
答案:
读写锁(ReadWriteLock)是Java中用于提高并发访问效率的一种锁机制,允许多个线程同时读取共享资源,但只有一个线程能够写入共享资源。它的主要作用包括:
- 改善多线程并发读取效率:多个线程可以同时读取共享资源,提高了读取操作的并发性。
- 保护写操作的数据一致性:写操作时,会独占锁,确保写操作的原子性和可见性。
- 在读多写少的场景中性能优于独占锁(如
ReentrantLock
),适合数据读取频繁但写入较少的应用场景。