You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何为LinkedHashSet加锁避免并发修改异常?

解决方案

1. 给所有集合操作加同一把锁

你之前只在序列化时加了锁,但如果其他线程修改集合(添加、删除元素)时没同步加锁,照样会触发并发修改异常。所有读写LinkedHashSet的地方,都要用synchronized(linkedHashSet)包裹:

// 添加元素示例
synchronized(linkedHashSet) {
    linkedHashSet.add(newElement)
}

// 删除元素示例
synchronized(linkedHashSet) {
    linkedHashSet.remove(oldElement)
}

确保所有操作都在同一锁的保护下,从根源避免并发冲突。

2. 序列化前先复制集合快照

如果担心序列化耗时太长、锁持有时间过久,可以在锁内先复制一份集合的快照,再对快照做序列化:

CoroutineScope(Dispatchers.IO).launch {
    val snapshot: LinkedHashSet<*>
    synchronized(linkedHashSet) {
        snapshot = LinkedHashSet(linkedHashSet) // 复制出完全独立的快照
    }
    // 对快照序列化,此时原集合可以正常被其他线程修改
    val jsonString = Gson().toJson(snapshot)
    sharedPreferences?.edit()?.putString("DataList", jsonString)?.apply()
}

这种方式缩短了锁的持有时间,只在复制快照时加锁,序列化操作在锁外执行,能提升并发性能。

3. 改用线程安全的包装集合

初始化集合时用Collections.synchronizedSet()包装LinkedHashSet,得到一个内置锁保护的线程安全集合:

// 初始化时就包装
val safeLinkedHashSet = Collections.synchronizedSet(LinkedHashSet<YourDataType>())

之后读写操作直接调用safeLinkedHashSet的方法即可,但注意遍历/序列化时仍需手动加锁(因为集合的迭代器本身不是线程安全的):

CoroutineScope(Dispatchers.IO).launch {
    synchronized(safeLinkedHashSet) {
        val jsonString = Gson().toJson(safeLinkedHashSet)
        sharedPreferences?.edit()?.putString("DataList", jsonString)?.apply()
    }
}

4. 用读写锁优化读多写少场景

如果你的业务里读操作(序列化、查询)远多于写操作(增删元素),可以用ReentrantReadWriteLock替代synchronized,读锁允许多线程同时访问,写锁互斥,能提升并发效率:

// 全局定义读写锁
val rwLock = ReentrantReadWriteLock()

// 写操作(添加/删除元素)示例
rwLock.writeLock().lock()
try {
    linkedHashSet.add(newElement)
} finally {
    rwLock.writeLock().unlock()
}

// 序列化(读操作)
CoroutineScope(Dispatchers.IO).launch {
    rwLock.readLock().lock()
    try {
        val jsonString = Gson().toJson(linkedHashSet)
        sharedPreferences?.edit()?.putString("DataList", jsonString)?.apply()
    } finally {
        rwLock.readLock().unlock()
    }
}

内容的提问来源于stack exchange,提问作者s k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:20:32