Java并发面试题, 你使用过 Java 的累加器吗?
Java并发面试题, 你使用过 Java 的累加器吗?
QA
Step 1
Q:: 你使用过 Java 的累加器(Accumulator)
吗?
A:: Java 中的累加器通常指的是 java.util.concurrent.atomic
包中的 AtomicInteger``,
AtomicLong
等原子类。这些类提供了线程安全的加减操作,而无需使用同步锁。这在多线程环境下非常有用,可以避免传统加锁带来的性能开销。例如,在一个高并发的计数器场景中,使用 AtomicInteger
可以确保计数器的正确性而不需要手动进行同步。
Step 2
Q:: AtomicInteger 和 Synchronized 有什么区别?
A:: AtomicInteger 是基于硬件的原子操作实现的,而 Synchronized 是基于锁机制实现的。前者在大多数情况下性能优于后者,因为它避免了线程上下文切换和阻塞操作。使用 AtomicInteger 可以直接实现无锁的线程安全操作,而 Synchronized 则会导致线程竞争和可能的锁等待。
Step 3
Q:: 什么是 CAS (Compare and Swap)
操作?
A:: CAS 是一种原子操作,用于实现无锁编程。在 Java 中,AtomicInteger
和 AtomicLong
等类的实现中就使用了 CAS 操作。CAS 操作比较一个变量的当前值与预期值,如果两者相等,则更新该变量的值为新值,否则不进行操作。CAS 操作是非阻塞的,能够避免线程被挂起。
Step 4
Q:: Java 中如何确保多线程环境下的安全性?
A:: 在 Java 中,多线程环境下的安全性通常通过以下方式确保:1) 使用原子类如 AtomicInteger、AtomicLong 等;2) 使用 Synchronized 关键字对共享资源进行加锁;3)
使用 java.util.concurrent
包中的工具类,如 ReentrantLock
,CountDownLatch
,Semaphore
等;4)
使用线程安全的集合类如 ConcurrentHashMap
、CopyOnWriteArrayList
等。
Step 5
Q:: 什么是锁的自旋?
A:: 自旋锁是一种锁机制,线程在尝试获取锁时不会立即进入阻塞状态,而是在一定时间内反复尝试获取锁。通过自旋避免了线程的上下文切换,提高了轻度锁竞争场景下的性能。但自旋会导致 CPU 资源的浪费,因此通常在自旋次数达到阈值后,线程会被挂起。Java 中的 ReentrantLock
就支持自旋锁。