多平台统一管理软件接口,如何实现多平台统一管理软件接口
334
2023-05-11
java 使用ConcurrentHashMap和计数器实现锁
java 使用ConcurrentHashMap和计数器实现锁
在某些场景下,我们想让线程根据某些业务数据进行排队,简单代码如下:
import java.util.ArrayovEQmOQIList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class TestServiceImpl {
private static ConcurrentHashMap
public void test(Long userId){
LockObj lock = tryLock(userId);
synchronized (lock) {
try{
//处理业务
}
finally{
unLock(lock);
}
}
}
private LockObj tryLock(Long key) {
LockObj curVal = new LockObj(key);
LockObj preVal = lockMap.putIfAbsent(key, curVal);
if (null == preVal) {
curVal.inc();
return curVal;
}
else{
preVal.inc();
}
return preVal;
}
private void unLock(LockObj lock){
if (lock.dec() <= 0){
lockMap.remove(lock.getKey());
}
}
public class LockObj {
private long key = 0;
private AtomicInteger count = new AtomicInteger(0);
public LockObj(long key){
this.key = key;
}
public int inc(){
return count.incrementAndGet();
}
public int dec(){
return count.decrementAndGet();
}
public long getKey(){
return key;
}
@Override
public String toString() {
return "LockObj [key=" + key + ", count=" + count + "]";
}
}
}
按照userId来排队,如果每个线程处理数据后不释放锁的话,那么可以不利用计数器。但是加了释放锁的操作,则必须加上计算器。因为当线程把锁释放掉后,还没来得及退出synchronized 代码块时,另外一个线程调用了tryLock方法,那该线程将拿到另外一个对象的锁,导致利用synchronized 关键字进行userId排队失败。
也可以利用guava的API来实现。
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
public class TestServiceImpl {
Interner
public void test(Long userId) throws OspException {
synchronized ( pool.intern(String.valueOf(userId))){
//处理业务操作
}
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~