Kotlin是否有Java Collections.synchronizedList等效实现?如何实现线程安全List?
首先直接给你结论:Kotlin标准库中的可变列表(比如mutableListOf()默认返回的ArrayList)本身并不是线程安全的。原因很简单——Kotlin的集合框架大多直接复用Java的实现,mutableListOf()底层就是Java的java.util.ArrayList,而这个类没有任何线程同步机制,多线程环境下同时读写会导致数据不一致甚至抛出ConcurrentModificationException。
接下来给你几种实用的实现线程安全List的方案:
1. 用Java同步集合快速包装
Java的Collections.synchronizedList()可以把普通可变列表一键包装成线程安全版本,Kotlin里可以直接调用:
import java.util.Collections val threadSafeList = Collections.synchronizedList(mutableListOf<String>())
⚠️ 注意:这个包装后的列表,迭代操作需要手动加锁,因为synchronizedList只保证单个方法的原子性,迭代是多个方法调用的组合(比如hasNext()+next()),不加锁会有并发问题。正确的迭代方式:
synchronized(threadSafeList) { threadSafeList.forEach { item -> // 处理每个元素 } }
2. 使用CopyOnWriteArrayList(读多写少场景首选)
如果你的业务是读操作远多于写操作,java.util.concurrent.CopyOnWriteArrayList是更优选择。它的核心逻辑是:每次写操作(添加、删除、修改)都会复制一份底层数组,读操作完全无锁,性能极高。Kotlin里直接实例化即可:
import java.util.concurrent.CopyOnWriteArrayList val threadSafeList = CopyOnWriteArrayList<String>()
它的优势是迭代时不需要加锁,因为迭代的是当前数组的快照,不会抛出并发修改异常,非常适合频繁读取、偶尔修改的场景。
3. 自定义线程安全列表(适合定制需求)
如果需要更灵活的控制(比如只同步特定操作、用更高效的锁),可以自己封装一个线程安全的List类,利用Kotlin的委托特性减少重复代码:
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.Lock class ThreadSafeMutableList<T> private constructor( private val delegate: MutableList<T>, private val lock: Lock = ReentrantLock() ) : MutableList<T> by delegate { companion object { fun <T> create(baseList: MutableList<T> = mutableListOf()): ThreadSafeMutableList<T> { return ThreadSafeMutableList(baseList) } } override fun add(element: T): Boolean { lock.lock() return try { delegate.add(element) } finally { lock.unlock() } } override fun remove(element: T): Boolean { lock.lock() return try { delegate.remove(element) } finally { lock.unlock() } } // 覆盖所有可变操作,比如addAll、removeAt、clear等,都用锁包裹 override fun clear() { lock.lock() try { delegate.clear() } finally { lock.unlock() } } }
这个方案可以根据业务需求选择锁的类型(比如公平锁、读写锁),或者只同步你需要的操作,灵活性拉满。
额外补充:不可变集合的线程安全
如果你的业务场景不需要修改集合内容,Kotlin的kotlinx.collections.immutable库提供的不可变集合本身就是线程安全的——因为不可变集合的状态一旦创建就不会改变,多线程读取完全没有问题。比如:
import kotlinx.collections.immutable.immutableListOf val immutableList = immutableListOf("item1", "item2")
不过如果需要频繁修改,还是得用前面的可变线程安全方案。
内容的提问来源于stack exchange,提问作者A.Sanchez.SD

