我想处理客户请求流。每个请求都有其特殊类型。首先,我需要初始化该类型的一些数据,然后我可以开始处理请求。当客户端类型第一次来的时候,我只是初始化相应的数据。此后,将使用该数据处理该类型的所有后续请求。
我需要以线程安全的方式执行此操作。
这是我写的代码。它是线程安全的吗?
public class Test {
private static Map<Integer, Object> clientTypesInitiated = new ConcurrentHashMap<Integer, Object>();
/* to process client request we need to
create corresponding client type data.
on the first signal we create that data,
on the second - we process the request*/
void onClientRequestReceived(int clientTypeIndex) {
if (clientTypesInitiated.put(clientTypeIndex, "") == null) {
//new client type index arrived, this type was never processed
//process data for that client type and put it into the map of types
Object clientTypeData = createClientTypeData(clientTypeIndex);
clientTypesInitiated.put(clientTypeIndex, clientTypeData);
} else {
//already existing index - we already have results and we can use them
processClientUsingClientTypeData(clientTypesInitiated.get(clientTypeIndex));
}
}
Object createClientTypeData(int clientIndex) {return new Object();}
void processClientUsingClientTypeData(Object clientTypeData) {}
}
一方面,ConcurrentHashMap 无法为同一个 A 生成两次 map.put(A,B) == null 。
另一方面,赋值和比较操作不是线程安全的。
那么这段代码可以吗?
如果没有,我该如何修复它?
更新:
我接受了 Martin Serrano 的回答,因为他的代码是线程安全的,并且不容易出现双重初始化问题。但我想指出的是,我没有发现我的版本有任何问题,作为答案发布在下面,并且我的版本不需要同步。
不,我不认为它仍然是线程安全的。
您需要将 put 操作包装在同步块中。
As per ConcurrentHashMap 的 javadoc http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html
检索操作(包括 get)通常不会阻塞,因此可能与更新操作(包括 put 和 remove)重叠。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)