Multithreading 如何使用观察者提供一个不可变的、线程安全的列表?
我经常使用StackOverflow,但没有问太多问题,因为我总是在某处找到答案。然而,对于这个困境,我似乎找不到一个好的解决办法 这就来了 我正在科特林建一座图书馆。我使用的是观察者模式 我有一个类监听来自第三方服务的传入消息,解析这些消息,并在可变列表中排队/添加解析的对象。该列表可以随时修改 同时,当列表发生更改时,可以通知任何订阅的观察员。现在,我已经对它进行了设置,因此列表是我的Observer方法中的一个参数 由于我没有使用Google的Guava库或KotlinX库,因为我想让这个库尽可能轻,所以我编写了一个ImmutableList的小实现,如下所示:Multithreading 如何使用观察者提供一个不可变的、线程安全的列表?,multithreading,list,kotlin,Multithreading,List,Kotlin,我经常使用StackOverflow,但没有问太多问题,因为我总是在某处找到答案。然而,对于这个困境,我似乎找不到一个好的解决办法 这就来了 我正在科特林建一座图书馆。我使用的是观察者模式 我有一个类监听来自第三方服务的传入消息,解析这些消息,并在可变列表中排队/添加解析的对象。该列表可以随时修改 同时,当列表发生更改时,可以通知任何订阅的观察员。现在,我已经对它进行了设置,因此列表是我的Observer方法中的一个参数 由于我没有使用Google的Guava库或KotlinX库,因为我想让这个
class ImmutableList<T>(list: MutableList<T>) : List<T> by list
// Extension to MutableList<T>
fun <T> MutableList<T>.toImmutableList() = ImmutableList(this)
所以我的问题是:
通过这样做,我可以确保我发送的列表是不可变的并且是线程安全的吗
我意识到基础列表仍然可以随时更改,导致我发送的列表与实际列表不同步。这就是为什么我使用观察者模型来更新列表。既然我想避免将底层列表暴露在库之外,那么这是实现我的目标的最佳方法吗
提前谢谢
通过这样做,我可以确保我发送的列表是不可变的并且是线程安全的吗
不,您发送的列表既不是不可变的,也不是线程安全的,因为正如您正确指出的,底层的MutableList
可以在以后的任何时间更改
要修复不可变列表的内容
,您应该制作其项目的防御性副本:
class ImmutableList<T>(list: List<T>) : List<T> { ... }
// Extension to MutableList<T>
fun <T> MutableList<T>.toImmutableList() = ImmutableList(this.toList())
类ImmutableList(list:list):list{…}
//可变列表的扩展
fun MutableList.toImmutableList()=不可变列表(this.toList())
这里的另一个问题是,通过list使用接口委托实现ImmutableList
类并不能正确实现list
类型:它的hashCode
,等于,以及toString
方法没有委托;相反,它们从Any
继承默认实现,因此违反了List
接口约定
您可以使用接口委派,但是您应该手动委派这3种方法。另外,值得编写一个子列表
的手动实现,它还将返回的子列表包装到不可变列表
中,以防止从外部修改它 谢谢你,伊利亚。我最终接受了您的建议,但保留了接口委派,并按照您的建议重写了hashCode
、equals
、toString
和子列表
方法。
observer.notifyListChanged(myMutableList.toImmutableList())
class ImmutableList<T>(list: List<T>) : List<T> { ... }
// Extension to MutableList<T>
fun <T> MutableList<T>.toImmutableList() = ImmutableList(this.toList())