我有一个数组,许多线程都在向该数组写入数据.但是,每个线程都有一个可以写入的预先分配的索引范围.此外,在完成所有线程之前,不会从数组中读取任何内容.

到目前为止,线程是安全的.当我需要扩展数组时,问题就出现了,当然,我的意思是将它换成复制第一个的更大的array.这只是偶尔做的(类似于ArrayList).

目前,我正在为数组的每一次写入获取一个锁.即使不需要为保持数组一致性而锁定,我也必须锁定,以防数组当前正在被复制/交换.

因为有很多写操作,所以我不想为它们加锁.我同意这样一种解决方案,即只有在复制和交换数组时才需要锁定写线程,因为这种情况很少发生.

但是,我不能仅在复制/交换正在进行时才施加写锁定,因为线程可能已经在向旧数组提交写操作.

我认为我需要某种屏障来等待所有写入完成,然后在我复制/交换数组时暂停线程.但CyclicBarrier将要求我准确地知道当前有多少线程处于活动状态,这不是微不足道的,而且可能容易受到边界条件的影响,在这种情况下,边界最终将永远等待,或者过早地降低自身.特别是,我不确定如何在屏障已经设置好的情况下处理进入的新线程,也不确定如何处理当前正在轮询作业(job)队列的线程,因此在没有新作业(job)的情况下永远不会减少屏障计数.

我可能必须实现一些(原子地)计算活动线程数并试图抢占所有边缘情况的东西.

但这可能是一个我不知道的"已解决"问题,所以我希望有一个比循环屏障/线程计数更简单(因此更好)的解决方案.理想情况下,它使用现有的实用程序类.

顺便说一句,我已经考虑过CopyOnWritearray.这对我没有用处,因为它为每次写入(大量写入)复制,而不仅仅是数组扩展.

还要注意,写入的 struct 几乎必须是数组,或基于array.

谢谢

推荐答案

虽然从技术上讲这是不正确的,但你可能可以使用ReadWriteLock.写入单个部分的线程都使用读锁(这是技术上不正确的部分,它们不是在读...),而调整大小使用了写锁.这样,所有写入线程都可以协同工作.调整大小必须等到所有分区写入完成后才能完成,这会阻塞整个array.完成此操作后,所有分区的写入都可以继续.

Java相关问答推荐

JPackage-results已安装-如何添加系统属性?

try 使用Java 9或更高版本对特殊对象图进行解析时出现NullPointerException

如何在Java中声明未使用的变量?

Java函数式编程中的双值单值映射

在模拟超类中设置非setter属性的值

在AVL树的Remove方法中使用NoSuchElementException时遇到问题

查找剩余的枚举

如何在ApachePOI中将图像添加到工作表的页眉?

在Spring Boot应用程序中导致";MediaTypeNotSupportdException&qot;的映像上载

解释左移在Java中的工作原理

OpenGL ES 3.0-纹理黑色

我可以在MacOS上使用什么Java函数来在适当的设备上以适当的音量播放适当的alert 声音?

Spring Boot&;Docker:无法执行目标org.springframework.boot:spring-boot-maven-plugin:3.2.0:build-image

buildDir:File!&#的getter解决方案是什么?39.被抛弃

Java中不兼容的泛型类型

try 使用预准备语句占位符获取信息时出现Try-With-Resources错误

有没有办法知道在合并中执行了什么操作?

如何使用外部函数从Java中获取C++ struct 的返回值&;内存API

为什么我得到默认方法的值而不是被覆盖的方法的值?

Maven创建带有特定类的Spring Boot jar和普通jar