近日在解决一个业务问题的时候,突然发现使用 Oracle Coherence 时,调用 NamedCache 的 get() 方法总是返回新的对象实例。
示例
package org.opoo.cache.coherence;
import java.io.Serializable;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
public class NamedCacheSample {
public static void main(String[] args) {
NamedCache cache = CacheFactory.getCache("sample");
Object data = new SampleData();
cache.put("1000", data);
System.out.println(data);
System.out.println(cache.get("1000"));
System.out.println(cache.get("1000"));
System.out.println(cache.get("1000"));
}
public static class SampleData implements Serializable{
private static final long serialVersionUID = 3353238636748170244L;
}
}
运行结果
2014-03-17 12:40:12.998/0.234 Oracle Coherence 3.6.1.0 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/D:/m2.repo/oracle-coherence/coherence/3.6.1.0-b19636/coherence-3.6.1.0-b19636.jar!/tangosol-coherence.xml" 2014-03-17 12:40:13.014/0.250 Oracle Coherence 3.6.1.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/D:/m2.repo/oracle-coherence/coherence/3.6.1.0-b19636/coherence-3.6.1.0-b19636.jar!/tangosol-coherence-override-dev.xml" Oracle Coherence Version 3.6.1.0 Build 19636 Grid Edition: Development mode Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. org.opoo.cache.coherence.NamedCacheSample$SampleData@1eec35 org.opoo.cache.coherence.NamedCacheSample$SampleData@77ef83 org.opoo.cache.coherence.NamedCacheSample$SampleData@1cb52ae org.opoo.cache.coherence.NamedCacheSample$SampleData@26d607
可见,缓存的对象和每次获取的对象实例都是不同的。
对象在 Coherence 中进行缓存时,会调用对象序列化(serialize)。在从缓存中读出时会调用反序列化(deserialize),每次调用反序列化都会创建一个新的对象实例。
所以,如果要反序列化单态类的对象实例,就需要实现 readResolve 方法来对返回实例进行替换。
基于 Coherence 上面所述的特点,下面的代码展示了一种错误的用法。
package org.opoo.cache.coherence;
import java.io.Serializable;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
public class NamedCacheSample2 {
public static class SampleData implements Serializable{
private static final long serialVersionUID = 3353238636748170244L;
public int status;
public String toString(){return super.toString() + "[status=" + status + "]";}
}
public static String KEY = "1000";
public static String CACHE_NAME = "sample";
public static void main(String[] args){
NamedCache cache = CacheFactory.getCache(CACHE_NAME);
SampleData data = new SampleData();
cache.put(KEY, data);
m1(cache);
}
public static void m1(NamedCache cache){
SampleData data1 = (SampleData) cache.get(KEY);
m2(cache);
if(data1.status > 0){
System.out.println("执行业务逻辑");
}else{
String string = String.format("业务逻辑未执行\n%s\n%s", data1, cache.get(KEY));
System.out.println(string);
}
}
public static void m2(NamedCache cache){
SampleData data2 = (SampleData) cache.get(KEY);
data2.status = 10;
//持久化对象
//saveToDatabase(data2);
cache.put(KEY, data2);
}
}
运行结果
业务代码未执行 org.opoo.cache.coherence.NamedCacheSample2$SampleData@15575e0[status=0] org.opoo.cache.coherence.NamedCacheSample2$SampleData@1addb59[status=10]
| Source |
|