0

以下のコードでは、静的メソッドgetCustomerIdByClientKeyが高スループット環境で複数のスレッドによって使用されます。

静的メソッドloadCustomersは約 10 分ごとに呼び出され、キャッシュを無効にして新しい顧客セットを読み込みます。顧客は追加または削除される場合があります。

気になるラインは、clientKeyToCustomerId = newClientKeyToCustomerId;

再割り当て時にスレッドが現在clientKeyToCustomerIdマップを使用している場合、そのスレッドは例外をスローしますか、それともメモリ空間で問題なく続行しますか、それとも JVM 全体を強制終了しますか? :)

パフォーマンスに悪影響を与えると思うので、マップにアクセスするブロックを同期したくありません。

map.clear()簡単に言えば、ルックアップにアクセスするスレッドは、そうすべきではないときに null の結果を返すため、呼び出したくありません。

マップを置き換えると問題が発生する場合、これを解決するためにどのようなアプローチをとりますか?

package com.mycompany.key;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.mycompany.dao.CustomerDao;
import com.mycompany.model.Customer;

public class CustomerManager {

    private static Map<String, String> clientKeyToCustomerId = 
                   new HashMap<String, String>();

    public static void loadCustomers() {
        List<Customer> allCustomers = new CustomerDao().loadAll();
        Map<String, String> newClientKeyToCustomerId = new HashMap<String, String>();
        for (Customer customer : allCustomers) {
            newClientKeyToCustomerId.put(customer.getActiveKey1(),
                    customer.getCustomerId());
            newClientKeyToCustomerId.put(customer.getActiveKey2(),
                    customer.getCustomerId());
        }
        clientKeyToCustomerId = newClientKeyToCustomerId;
    }

    public static String getCustomerIdByClientKey(String pClientKey) {
        return clientKeyToCustomerId.get(pClientKey);
    }

}
4

1 に答える 1

1

volatileについて読むように言われた後、この質問で受け入れられた答えは、VolatileHashMapとConcurrentHashMapを解決すると思います。以下のコードを変更しました。volatileキーワードは、スレッドを停止します-マップをローカルにキャッシュします。

古いマップから現在読み取っているスレッドは古くなっていますが、ビジネスの観点からは問題ありません。

package com.mycompany.key;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.mycompany.dao.CustomerDao;
import com.mycompany.model.Customer;

public class CustomerManager {

    //private static Map<String, String> clientKeyToCustomerId = 
    // new HashMap<String, String>();
    private volatile static Map<String, String> clientKeyToCustomerId = 
               new HashMap<String, String>();

    public static void loadCustomers() {
        List<Customer> allCustomers = new CustomerDao().loadAll();
        Map<String, String> newClientKeyToCustomerId = new HashMap<String, String>();
        for (Customer customer : allCustomers) {
            newClientKeyToCustomerId.put(customer.getActiveKey1(),
                    customer.getCustomerId());
            newClientKeyToCustomerId.put(customer.getActiveKey2(),
                    customer.getCustomerId());
        }
        clientKeyToCustomerId = newClientKeyToCustomerId;
    }

    public static String getCustomerIdByClientKey(String pClientKey) {
        return clientKeyToCustomerId.get(pClientKey);
    }

}
于 2013-02-28T14:55:52.290 に答える