在下面的代码中,静态方法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);
}
}
答案 0 :(得分:1)
在被告知阅读volatile之后,我认为这个问题中接受的答案解决了它Volatile HashMap vs 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);
}
}