Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 所有CRUD操作的线程安全列表_Java_Multithreading - Fatal编程技术网

Java 所有CRUD操作的线程安全列表

Java 所有CRUD操作的线程安全列表,java,multithreading,Java,Multithreading,最近,我进行了一次编码练习,我必须创建以下三项服务: 创建:创建新事务 获取:在过去60秒内获取所有记录并删除任何旧记录 删除:删除所有交易记录 因此,对于这些服务,我为事务存储创建了下面的类。但是根据我的代码审查员的说法,下面的代码不是线程安全的 由于使用多种方法添加和删除过时的事务,因此存在有效事务可能丢失的情况 有人能回顾一下下面的代码,并告诉我在线程安全性和性能方面可以改进什么吗 public class TransactionMemory { private List&l

最近,我进行了一次编码练习,我必须创建以下三项服务:

  • 创建:创建新事务
  • 获取:在过去60秒内获取所有记录并删除任何旧记录
  • 删除:删除所有交易记录
因此,对于这些服务,我为事务存储创建了下面的类。但是根据我的代码审查员的说法,下面的代码不是线程安全的

由于使用多种方法添加和删除过时的事务,因此存在有效事务可能丢失的情况

有人能回顾一下下面的代码,并告诉我在线程安全性和性能方面可以改进什么吗

public class TransactionMemory {

    private List<Transaction> transactions = new CopyOnWriteArrayList<>();

    public void newTransaction(Transaction transaction) {

        transactions.add(transaction);
    }

    public List<Transaction> trxsInLast60Seconds() {
        List<Transaction> filteredTransactions = transactions.stream()
                .filter(p -> Instant.parse(p.getTimestamp()).isAfter(DateHelperUtils.getLast60SecondsByNow()))
                .collect(Collectors.toList());
        removeOldTransactions(filteredTransactions);
        return filteredTransactions;
    }

    private void removeOldTransactions(List<Transaction> filteredTransactions){
        transactions.retainAll(filteredTransactions);
    }
    public void deleteTransactions() {
        transactions.clear();
    }
}
公共类TransactionMemory{
私有列表事务=新建CopyOnWriteArrayList();
公共无效新交易(交易){
交易。添加(交易);
}
公共列表TRXSINLAST60秒(){
List filteredTransactions=transactions.stream()
.filter(p->Instant.parse(p.getTimestamp()).isAfter(DateHelperUtils.getLast60SecondsByNow())
.collect(Collectors.toList());
移除旧交易(过滤交易);
返回过滤传输;
}
private void removeOldTransactions(列表筛选交易){
交易。保留(过滤交易);
}
公共事务(){
transactions.clear();
}
}
类确实是线程安全的,但由于

所有可变操作(添加、设置等)都由 创建基础数组的新副本

下面是一个使用
ArrayList
的解决方案:

public class TransactionMemory {

    private final List<Transaction> transactions = new ArrayList<>();

    public synchronized void newTransaction(Transaction transaction) {
        transactions.add(transaction);
    }

    public synchronized List<Transaction> trxsInLast60Seconds() {
        List<Transaction> filteredTransactions = transactions.stream()
                .filter(p -> Instant.parse(p.getTimestamp()).isAfter(DateHelperUtils.getLast60SecondsByNow()))
                .collect(Collectors.toList());
        removeOldTransactions(filteredTransactions);
        return filteredTransactions;
    }

    private void removeOldTransactions(List<Transaction> filteredTransactions) {
        transactions.retainAll(filteredTransactions);
    }

    public synchronized void deleteTransactions() {
        transactions.clear();
    }
}
公共类TransactionMemory{
私有最终列表事务=新建ArrayList();
公共同步作废新交易(交易){
交易。添加(交易);
}
公共同步列表trxsInLast60Seconds(){
List filteredTransactions=transactions.stream()
.filter(p->Instant.parse(p.getTimestamp()).isAfter(DateHelperUtils.getLast60SecondsByNow())
.collect(Collectors.toList());
移除旧交易(过滤交易);
返回过滤传输;
}
private void removeOldTransactions(列表筛选交易){
交易。保留(过滤交易);
}
公共同步的void deleteTransactions(){
transactions.clear();
}
}

因为所有的变异操作都是同步的,所以它是线程安全的。

我看不到任何线程安全问题。随着
事务的增长,性能将下降,因为每个
add()
retainAll()
最终都需要复制底层数组。请注意,当流筛选器正在进行时,任何修改
事务的方法都必须等待,然后才能复制阵列的底层数据,而正在进行的流筛选器将看不到修改。感谢@AndrewS的回复。那么,我如何改进代码,以便我们能够看到实时修改/数据呢?请参阅@aka one的答案-同步这些方法意味着一次只有一个线程可以访问
事务
(假设线程共享相同的
TransactionMemory
实例)。感谢@aka one的回复。但是当两个线程同时修改集合时会发生什么呢。通过使用新的转换方法2。通过使用TRXSINLAST60秒方法?我们去取回实时数据好吗?对不起,我关了账户。发布另一个问题,让某人向你解释为什么你的情景没有发生