首页 > 解决方案 > Java 并发:CopyOnWriteArrayList 行为

问题描述

我需要将一些对象存储到数据库中。

首先,

  1. 我将它们存储在内存中(放入集合中)
  2. 当其中一个正确存储在数据库中时,我将其删除

所以,

public class AuditService {
    private CopyOnWriteArrayList<Audit> copyWrite;

    public void flush(Audit... audits) {
        Collection<Audit> auditCollection = Arrays.asList(audits);
        this.copyWrite.addAll(auditCollection);

        this.copyWrite.forEach(audit -> {
            // save audit object on database
            this.copyWrite.remove(audit);

        });
    }
}

我必须是线程安全的,我的意思是,AuditService是一个单例类,我的几个线程可以同时到达 atflush方法。

我的问题是:

  1. CopyOnWriteArrayList为了解决并发问题,它是如何工作的。
  2. 这段代码正确吗?

标签: javamultithreadingjava.util.concurrent

解决方案


CopyOnWriteArrayList通过在数据更改时复制底层数组来提供线程安全。像您的示例中那样的 Mutator 操作addAll()在内部由CopyOnWriteArrayList.

但是,您的代码没有什么意义,因为copyWrite在方法之外无法访问字段flush()。局部方法变量是线程安全的,因此您的代码可以简化为:

public void flush(Audit... audits) {
    for (Audit a : audits) {
        // save audit object on database
    }
}

问题是如果Audit对象被修改会发生什么。希望您使它们不可变,因为更改Audit事件几乎没有意义。


推荐阅读