Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何使用观察者提供一个不可变的、线程安全的列表?_Multithreading_List_Kotlin - Fatal编程技术网

Multithreading 如何使用观察者提供一个不可变的、线程安全的列表?

Multithreading 如何使用观察者提供一个不可变的、线程安全的列表?,multithreading,list,kotlin,Multithreading,List,Kotlin,我经常使用StackOverflow,但没有问太多问题,因为我总是在某处找到答案。然而,对于这个困境,我似乎找不到一个好的解决办法 这就来了 我正在科特林建一座图书馆。我使用的是观察者模式 我有一个类监听来自第三方服务的传入消息,解析这些消息,并在可变列表中排队/添加解析的对象。该列表可以随时修改 同时,当列表发生更改时,可以通知任何订阅的观察员。现在,我已经对它进行了设置,因此列表是我的Observer方法中的一个参数 由于我没有使用Google的Guava库或KotlinX库,因为我想让这个

我经常使用StackOverflow,但没有问太多问题,因为我总是在某处找到答案。然而,对于这个困境,我似乎找不到一个好的解决办法

这就来了

我正在科特林建一座图书馆。我使用的是观察者模式

我有一个类监听来自第三方服务的传入消息,解析这些消息,并在可变列表中排队/添加解析的对象。该列表可以随时修改

同时,当列表发生更改时,可以通知任何订阅的观察员。现在,我已经对它进行了设置,因此列表是我的Observer方法中的一个参数

由于我没有使用Google的Guava库或KotlinX库,因为我想让这个库尽可能轻,所以我编写了一个ImmutableList的小实现,如下所示:

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())