java 使用ConcurrentHashMap和计数器实现锁
程序员文章站
2023-12-20 21:28:04
java 使用concurrenthashmap和计数器实现锁
在某些场景下,我们想让线程根据某些业务数据进行排队,简单代码如下:
import java.ut...
java 使用concurrenthashmap和计数器实现锁
在某些场景下,我们想让线程根据某些业务数据进行排队,简单代码如下:
import java.util.arraylist; 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<long, lockobj> lockmap = new concurrenthashmap<long, lockobj>(40); 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<string> pool = interners.newweakinterner(); public void test(long userid) throws ospexception { synchronized ( pool.intern(string.valueof(userid))){ //处理业务操作 } } }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
推荐阅读
-
java 使用ConcurrentHashMap和计数器实现锁
-
使用JAVA实现高并发无锁数据库操作步骤分享
-
Java使用IO流实现音频的剪切和拼接
-
Java多线程Queue、BlockingQueue和使用BlockingQueue实现生产消费者模型方法解析
-
Java使用桥接模式实现开关和电灯照明功能详解
-
Java使用桥接模式实现开关和电灯照明功能详解
-
详解java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝)
-
Android下拉列表(Spinner)效果(使用C#和Java分别实现)
-
Android仿微信菜单(Menu)(使用C#和Java分别实现)
-
Android相册效果(使用C#和Java分别实现)