并发 - 仅当记录具有特定状态时才插入到映射中

问题描述 投票:0回答:1

我想更改以下代码片段。目前,它从列表中读取并创建一个以 transactionId 为键的映射,并且无论对象的状态如何,它都会覆盖存储在映射中的元素。 PaymentDetailsModel 包含交易 ID 和状态作为属性。

        Map<String, PaymentDetailsModel> transactions = new HashMap<>();
        allPaymentActivityRecords.stream()
                .forEach(paymentDetail -> transactions.put(paymentDetail.getTransactionId(), paymentDetail));
        return transactions;

我想更改它,以便如果存储的值具有 STATUS2 并且即将到来的记录具有 STATUS1,则不会发生覆盖。 在代码中,它看起来像这样:

private Map<String, PaymentDetailsModel> process(List<PaymentDetailsModel> allPaymentActivityRecords){
        Map<String, PaymentDetailsModel> transactions = new HashMap<>();

        for (PaymentDetailsModel paymentDetail : allPaymentActivityRecords) {
            PaymentDetailsModel paymentDetailsModel = transactions(paymentDetail.getTransactionId());
            if (paymentDetailsModel == null || !shouldNotOverrideStates(paymentDetail, paymentDetailsModel)) {
                transactions.put(paymentDetail.getTransactionId(), paymentDetail);
            }
        }
        return transactions;

   private static boolean shouldNotOverrideStates(PaymentDetailsModel paymentDetail, PaymentDetailsModel paymentDetailsModel) {
        return STATUS2.equals(paymentDetailsModel.getStatus()) && STATUS1.equals(paymentDetail.getStatus());
    }

我担心的是,如果此代码在多个线程上并行运行,此解决方案可能会遇到并发问题。在保证正确性的想法中,我有条件同步或者使用ConcurrentHashMap。请告诉我你的想法。

java concurrency hashmap
1个回答
0
投票

您应该使用

ConcurrentHashMap
及其
compute
方法,该方法是原子处理的:

    Map<String, PaymentDetailsModel> transactions = new ConcurrentHashMap<>();

    for (PaymentDetailsModel paymentDetail : allPaymentActivityRecords) {
        PaymentDetailsModel paymentDetailsModel = transactions.compute(
                paymentDetail.getTransactionId(),
                (k, v) -> {
                    if (v == null || !shouldNotOverrideStates(paymentDetail, v)) {
                        return paymentDetail;
                    } else {
                        return v;
                    }
                }
            );
        }
© www.soinside.com 2019 - 2024. All rights reserved.