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秒方法?我们去取回实时数据好吗?对不起,我关了账户。发布另一个问题,让某人向你解释为什么你的情景没有发生