我有多个计数器对象的情况。每个计数器对象可以同时由多个线程递增,因此所有对象都有一组ReentrantLock,而且效果很好-每个对象在给定的时刻只能由一个线程修改。
这里有个要点:有一个过程每15分钟运行一次,并收集所有计数器对象,进行一些计算并清除计数器。该线程没有锁定任何东西,因此存在以下情况:
在这种情况下,计数器对象之一被弄乱了,因为最后清除操作被丢弃,并且计数器的状态与清除之前的状态相同。
我想要的是:
我有备份计划:
如您所见,我有一些选择,但是我想知道是否有更好的方法可以做到这一点。
更新
我被要求提供代码,就这样了。
下面是增加对象上的计数器的方法之一的示例。
public void sipIncomingCall(String objName) {
try {
lock(objName);
Stats stat = getStatisticsForObj(objName);
long l = stat.getSipIncomingConnections().incrementAndGet();
stat.getSipConnectionsSum().incrementAndGet();
LOGGER.debug("incrementing sip incoming connections to {}, objName {}", l, objName);
putStatisticsForObj(objName, stat);
}finally {
unlock(objName);
}
}
lock()和unlock()方法:private Map<String,ReentrantLock> locks = new ConcurrentHashMap<>();
protected void lock(String key) {
ReentrantLock lock = locks.getOrDefault(key, new ReentrantLock());
lock.lock();
}
protected void unlock(String key){
ReentrantLock lock = locks.get(key);
if(lock!=null){
lock.unlock();
}
}
方法getStatisticsForObj()和putStatisticsForObj():private MgcfStats getStatisticsForObj(String tgName) {
//get object from local cache (or hazelcast)
return Cluster.getTgStatistics(tgName);
}
private void putStatisticsForObj(String tgName,MgcfStats stats){
//saving to local cache and hazelcast
Cluster.putTgStatistics(tgName,stats);
}
以下是“clearing_thread”的片段,该片段将所有统计信息对象复制到本地映射,然后在“群集”中清除统计信息: statisticsData.setObjStats(new HashMap<>(Cluster.getTgStatistics()));
Cluster.clearTgStatistics();
最佳答案
您可以使用ReadWriteLock
。
您仍需要为每个计数器设置单独的锁。
关于java - 检查是否持有锁,如果空闲则不锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64023620/