我正在与jcs一起使用一台远程缓存服务器的更多客户端。
这是服务器配置:
registry.host = xx.xx.xx.xx Registry.port = 1104
remote.cache.service.port = 1104
remote.cache.rmiSocketFactoryTimeoutMillis = 5000
remote.cluster.LocalClusterConsistency = true
remote.cluster.AllowClusterGet = true
jcs.default = DC
jcs.default.cacheattributes = org.apache.commons.jcs.engine.CompositeCacheAttributes jcs.default.cacheattributes.MaxObjects = 100 jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds = 1800 jcs.default.cacheattributes.UseMemoryShrinker = true
jcs.default.elementattributes.IsEternal = false jcs.default.elementattributes = org.apache.commons.jcs.engine.ElementAttributes
jcs.auxiliary.DC = org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory jcs.auxiliary.DC.attributes = org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.DC.attributes.DiskPath = / home / java / conf / data jcs.auxiliary.DC.attributes.MaxPurgatorySize = 1000
jcs.auxiliary.DC.attributes.MaxKeySize = 1000 jcs.auxiliary.DC.attributes.OptimizeAtRemoveCount = 300 jcs.auxiliary.DC.attributes.OptimizeOnShutdown = true jcs.auxiliary.DC.attributes.ClearDiskOnStartup = true jcs.auxiliary.DC.attributes.DiskLimitType = SIZE
以及客户端配置:
jcs.auxiliary.RC = org.apache.commons.jcs.auxiliary.remote.RemoteCacheFactory jcs.auxiliary.RC.attributes = org.apache.commons.jcs.auxiliary.remote.RemoteCacheAttributes jcs.auxiliary.RC.attributes.FailoverServers = xx.xx.xx.xx:1104 jcs.auxiliary.RC.attributes.RemoveUponRemotePut = false
jcs.auxiliary.RC.attributes.Receive = false jcs.auxiliary.RC.elementattributes.UseMemoryShrinker = true
将客户代码放在这里:
public class JcsSharedCache<K, V> implements ICache<K, V> {
private CompositeCache<K, V> internal;
public void put(K key, V value) throws BeCacheException {
try {
synchronized(this){
internal.update(new CacheElement<>(internal.getCacheName(), key, value, internal.getElementAttributes()));
}
} catch (Exception ex) {
throw new BeCacheException(ex);
}
}
}
有时,客户端会收到ConcurrentModificationException,而jcs会禁用远程放置。每个客户端都有一个puts的同步版本,但是(在我看来)这是在两个客户端尝试同时将某些内容放入同一缓存时发生的。
有办法避免这种行为吗?
在堆栈跟踪下面:
2018-07-10 18:02:52错误RemoteCache:141-由于禁用远程缓存 错误:无法将[da4a81e6-85df-426a-b6f6-a5b6777b0891]放入 节点java.util.ConcurrentModificationException 在java.util.HashMap $ HashIterator.nextNode(HashMap.java:1442) 在java.util.HashMap $ KeyIterator.next(HashMap.java:1466) 在java.util.HashSet.writeObject(HashSet.java:287) 在sun.reflect.GeneratedMethodAccessor135.invoke(未知来源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:498) 在java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1128) 在java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) 在java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 在java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 在java.util.HashMap.internalWriteEntries(HashMap.java:1790) 在java.util.HashMap.writeObject(HashMap.java:1363) 在sun.reflect.GeneratedMethodAccessor132.invoke(未知来源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:498) 在java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1128) 在java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) 在java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 在java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 在java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 在java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 在java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 在java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 在java.util.ArrayList.writeObject(ArrayList.java:766) 在sun.reflect.GeneratedMethodAccessor128.invoke(未知来源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:498) 在java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1128) 在java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) 在java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 在java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 在java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 在org.apache.commons.jcs.utils.serialization.StandardSerializer.serialize(StandardSerializer.java:55) 在org.apache.commons.jcs.utils.serialization.SerializationConversionUtil.getSerializedCacheElement(SerializationConversionUtil.java:74) 在org.apache.commons.jcs.auxiliary.remote.AbstractRemoteAuxiliaryCache.processUpdate(AbstractRemoteAuxiliaryCache.java:421) 在org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheEventLogging.updateWithEventLogging(AbstractAuxiliaryCacheEventLogging.java:65) 在org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheEventLogging.update(AbstractAuxiliaryCacheEventLogging.java:50) 在org.apache.commons.jcs.engine.CacheAdaptor.handlePut(CacheAdaptor.java:96) 在org.apache.commons.jcs.engine.AbstractCacheEventQueue $ PutEvent.doRun(AbstractCacheEventQueue.java:362) 在org.apache.commons.jcs.engine.AbstractCacheEventQueue $ AbstractCacheEvent.run(AbstractCacheEventQueue.java:281) 在org.apache.commons.jcs.engine.CacheEventQueue $ QProcessor.run(CacheEventQueue.java:228)