java - 编写一个包含整数的 ArrayList,该整数将被并发访问

标签 java multithreading concurrency synchronization atomic

要求是,我需要编写一个整数的ArrayList。我需要对不同整数进行线程安全访问(写入、读取、增加、减少),并且还需要允许最大并发性。

每个整数的运算也很特殊,如下所示:

  1. 最频繁的操作是读取
  2. 第二个频繁操作是仅当值大于零时才减一。或者,增加一(无条件)
  3. 添加/删除元素的情况很少见,但仍然需要。

我想到了 AtomicInteger。然而,这变得不可用,因为我想要的原子操作是比较如果不为零,然后减少。然而,AtomicInteger 提供的原子操作是比较是否相等,然后设置。如果您知道如何在这种情况下应用 AtomicInteger,请在此处提出。

我的想法是同步对每个整数的访问,如下所示:

ArrayList <Integer> list;
 ... ...
// Compare if greater than zero, and decrease
MutableInt n = list.get(index);
boolean success = false;
synchronized (n) {
    if (n.intValue()>0) { n.decrement(); success=true; }
}

// To add one
MutableInt n = list.get(index);
synchronized (n) {
    n.increment();
}

// To just read, I am thinking no need synchronization at all.
int n = list.get(index).intValue();

我的解决方案有副作用吗?维护数百甚至数千个同步整数是否有效?

更新:我还认为允许并发访问每个元素是不实际的,也没有好处,因为实际的并发访问受到处理器数量的限制。也许我只是使用几个同步对象来保护List的不同部分,那么就足够了?

然后就是实现增删改操作,它是线程安全的,但是不会对其他操作的并发造成太大影响。我在想ReadWriteLock,对于添加/删除,需要获取写锁,对于其他操作(更改一个整数的值),需要获取读锁。这是正确的做法吗?

最佳答案

我认为您使用读锁来访问列表并使用写锁来添加/删除列表是正确的。

您仍然可以使用 AtomicInteger 作为值:

// Increase value
value.incrementAndGet()

// Decrease value, lower bound is 0
do {
    int num = value.get();
    if (num == 0)
        break;
} while (! value.compareAndSet(num, num - 1)); // try again if concurrently updated

关于java - 编写一个包含整数的 ArrayList,该整数将被并发访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32929816/

相关文章:

java - Android数据报套接字用于udp发送

c++ - "release sequence"是什么意思?

C++ getline(string) 与多线程有关的段错误

c# - 具有返回类型的线程

Java线程从共享堆栈数组读取和写入

java - 用 Java 设计数据访问类

java - 更快地插入 Oracle 哈希簇表

java - 以 O(1) 空间复杂度对 O(n log n) 中的链表进行排序

java - 每秒 3K 传入请求的重复检测,推荐的数据结构/算法?

python - concurrent.futures.as_completed 是如何工作的?