How to Implement a Thread-Safe Resizable Array in Java

2025年5月5日 | 阅读 4 分钟

在使用线程安全的动态数组时,多个线程可以执行插入和删除等操作,而不会有数据损坏的风险。虽然 ArrayList 类是 Java 的标准类,但默认情况下它不是线程安全的。可以使用并发集合或同步来确保线程安全。我们可以通过使用并发集合,如 Collections.synchronizedList 或 CopyOnWriteArrayList 来生成一个线程安全的动态数组。通过确保一次只有一个线程可以访问该数组,同步有助于防止数据损坏。

Java 中,你可以在实现线程安全的动态数组时,使用同步方法来处理并发修改并确保安全扩展。

实现线程安全动态数组的不同方法

方法:使用同步方法

为了让数组一次只能被一个线程修改,同步添加、删除和调整元素大小的方法。

在此示例中,使用 Collections.synchronizedList 创建了一个线程安全的动态数组。synchronizedList 函数通过包装现有列表来创建一个同步(线程安全)列表。

实施

文件名: ThreadSynchronizedList.java

输出

 
The elements present in the array is: 
10
20
30
40
50   

方法:使用 CopyOnWriteArrayList

得益于 java.util.concurrent 包,这里有一个 Java 自带的动态、线程安全数组。每次进行更改时,都会创建一个底层数组的新副本,以确保线程安全。然而,对于频繁更新的列表,这可能会消耗大量内存。

线程安全由并发集合(如 CopyOnWriteArrayList)提供,它们不需要显式同步。每次添加或修改元素时,都会创建一个底层数组的新副本,以确保安全迭代。

实施

文件名: ThreadCopyWriteArrayList.java

输出

 
The elements present in the array is: 
10
20
30
40
50   

方法:使用 ReentrantLock

为了提供安全的并发访问,该代码使用泛型和 ReentrantLock 在 Java 中定义了一个动态、线程安全的数组。为了存储泛型元素 (T),类 ThreadSafeResizableArray 包含一个构造函数,该构造函数以指定的初始容量初始化数组。当 add 方法(已锁定)向数组添加元素时,通过将现有元素复制到新的、更大的数组来加倍数组的容量。

如果数组的当前大小超过其限制,则会触发 resize 函数。除了使用锁定在管理可能的 IndexOutOfBoundsExceptions 时维护线程安全外,get 函数还允许检索指定索引处的元素。

实施

文件名: ThreadSafeResizableArray.java

输出

 
The elements in the array is:
10
20
30
40
50   

下一个主题ATM 程序 Java