最近我进行了编码练习,必须创建以下三个服务:
因此,对于这些服务,我创建了以下用于事务存储的类。但是根据我的代码审阅者的说法,以下代码不是线程安全的。
由于使用多种方法添加和删除过时的交易,在某些情况下可能会丢失有效的交易。
有人可以查看以下代码,并告诉我在线程安全性和性能方面我可以改进的地方吗?
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();
}
}
答案 0 :(得分:2)
CopyOnWriteArrayList
类确实是线程安全的,但是由于
所有可变操作(添加,设置等)均由以下方式实现 制作基础数组的新副本
这是使用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();
}
}
由于所有可变操作都已同步,因此它是线程安全的。