首页 / 知识
关于多线程:Java集合的不可修改包装器会使它们线程安全吗?
2023-04-16 21:03:00

Does the unmodifiable wrapper for java collections make them thread safe?我需要使ArrayLists线程的ArrayList安全。 我也不能让客户对集合进行更改。 不可修改的包装器会使其线程安全吗,或者我需要在集合上使用两个包装器? 这取决于。包装器只会阻止对其包装的集合进行更改,而不是对集合中的对象进行更改。如果您有一个ArrayLists的ArrayList,则全局列表及其每个元素列表都需要单独包装,并且您可能还需要为这些列表的内容做些事情。最后,您必须确保原始列表对象没有更改,因为包装器仅阻止通过包装器引用而不是原始对象的更改。 在这种情况下,您不需要同步包装器。
关于一个相关主题-我已经看到了几条建议使用同步集合以实现线程安全的回复。
不可修改的包装器仅阻止更改其适用的列表的结构。如果此列表包含其他列表,并且您有尝试修改这些嵌套列表的线程,那么您将无法避免发生并行修改风险。 如果安全地发布了不可修改的视图,并且发布了不可修改的视图之后,则永远都不会修改可修改的原始文档(包括集合中递归包含的所有对象!),它将是线程安全的。 如果您想继续修改原始图,则可以创建集合对象图的防御性副本并返回该图的不可修改视图,或者使用固有的线程安全列表作为开头,然后返回该图的不可修改视图。 那。 如果您以后仍然打算不同步地访问List,则不能返回unmodifiableList(synchonizedList(theList))。 如果在多个线程之间共享可变状态,则所有线程在访问该状态时必须在相同的锁上进行同步。 根据定义,不可变对象是线程安全的(假设没有人保留对原始集合的引用),因此不需要同步。
使用Collections.unmodifiableList()包装外部ArrayList
也使用Collections.unmodifiableList()包装内部ArrayList
让我们知道此解决方案是否会引起问题(开销,内存使用情况等); 编辑:当然,如果列表被修改,它们不是线程安全的。我假设没有进一步的编辑。 我相信,因为UnmodifiableList包装器将ArrayList存储到最终字段,所以只要创建包装器后未修改列表,包装器上的任何读取方法都将看到构造包装器时的列表,并且只要包装器内部的可变ArrayList不被修改(包装器无法防范)。 通过查看"集合"源,看起来"不可修改"不会使其同步。
同步类包装器中有一个互斥对象来完成同步部分,因此看起来您需要同时使用两者。还是自己滚! 不知道我是否理解您要做什么,但我会说大多数情况下的答案是"否"。 如果将ArrayList和ArrayList设置为ArrayList和ArrayList,则在创建后就永远不能更改外部列表和内部列表(并且在创建过程中,只有一个线程可以访问内部列表和外部列表),它们可能被包装器线程安全(如果同时,外部列表和内部列表以无法修改的方式包装)。 ArrayList上的所有只读操作很可能是线程安全的。但是,Sun不能保证它们是线程安全的(也不适用于只读操作),因此,即使它可能现在就可以工作,但将来可能会中断(如果Sun创建了一些内部数据缓存来更快地访问它们)。例)。 在以下情况下这是必需的: 如果仅打算按索引从ArrayList中读取,则可以假定这是线程安全的。 如有疑问,请选择同步包装器。 |
最新内容
相关内容
修改时间命令linux?
修改时间命令linux?,时间,系统,命令,大陆,国家,信息,时区,终端,时分,日期,如何修改linux系统时间?inux修改时间命令是date-s+时分秒。修改linulinux中路径修改命令?
linux中路径修改命令?,系统,命令,首次,工作,名称,目录,文件,环境变量,路径,格式,如何修改Linux系统下的PATH1、之前介绍的使用 export 命令设linux修改脚本的命令?
linux修改脚本的命令?,系统,密码,服务,工作,工具,环境,信息,百度,代码,脚本,求一个批量ssh登录linux服务器,修改配置文件的脚本参考一下。_百linux修改命令所属组?
linux修改命令所属组?,系统,信息,档案,工具,状态,文件,命令,设备,检测,环境,linux系统下怎么修改文件所属用户和组?1、linux怎么修改文件所属linux下修改端口命令?
linux下修改端口命令?,代码,服务,端口,系统,文件,编辑,后果,命令,字段,下面,Linux操作系统下SSH默认22端口修改方法假如要改SSH的默认端口(22),那linux修改名称命令?
linux修改名称命令?,系统,名称,图片,查询系统,代码,名字,命令,用户,文件名,批量,linux怎么修改计算机名称1、在提示符下输入vi/etc/hosts,然后linux修改时区的命令?
linux修改时区的命令?,时间,系统,大陆,国家,标准,时区,命令,日期,终端,方法,Linux中如何查看修改系统的时间和时区目录方法1:使用命令行打开终linux网络修改命令?
linux网络修改命令?,地址,网络,系统,工作,服务,代码,管理,命令,工具,设备,Linux必学的网络操作命令Linux的网络命令比较多,其中一些命令像pinglinux修改内存命令?
linux修改内存命令?,系统,信息,标准,工具,数据,在线,内存,命令,分区,大小,Linux系统中的内存清理和释放命令归纳第一步:先执行sync命令 sync sylinux修改用户名命令?
linux修改用户名命令?,系统,密码,查询系统,代码,数字,用户名,命令,第三,电脑,第一,linux怎样修改用户名和主机名以 root 用户登录系统或者使用linux命令换行后修改?
linux命令换行后修改?,服务,系统,本行,代码,环境,工作,命令,文件,终端,字符,在LINUX命令行中要怎么换行?1、命令行窗口按Enter换行。命令提示linux修改端口号命令?
linux修改端口号命令?,代码,服务,系统,端口,工作,邮箱,文件,编辑,命令,后果,在linux下登录ssh如何指定端口?SSH 默认使用的端口号是 22。大多