当前位置: 移动技术网 > IT编程>开发语言>Java > java基于ConcurrentHashMap设计细粒度实现代码

java基于ConcurrentHashMap设计细粒度实现代码

2019年07月19日  | 移动技术网IT编程  | 我要评论

细粒度锁:

       java中的几种锁:,reentrantlock,reentrantreadwritelock已基本可以满足编程需求,但其粒度都太大,同一时刻只有一个线程能进入同步块,这对于某些高并发的场景并不适用。比如银行客户a向b转账,c向d转账,假如这两个线程并发,代码其实不需要同步。但是同时有线程3,e向b转账,那么对b而言必须加入同步。这时需要考虑锁的粒度问题,即细粒度锁。

    网上搜寻了一些关于java细粒度锁的介绍文章,大部分是提供思路,比如,string.intern()和类concurrenthashmap,本人对第三种比较感兴趣,为此研究了下concurrenthashmap的源码。基于concurrenthashmap设计细粒度大志思路如下

map locks = new map();
 list lockkeys = new list();
for (int number : 1 - 10000) {
	object lockkey = new object();
	lockkeys.add(lockkey);
	locks.put(lockkey, new object());
}
public void dosomething(string uid) {
	object lockkey = lockkeys.get(uid.hash() % lockkeys.size());
	object lock = locks.get(lockkey);
	synchronized(lock) {
		// do something
	}
}

具体实现如下:

public class lockpool {
	//用户map
	private static concurrenthashmap<string,object> usermap=new concurrenthashmap<string,object>();
	//用户金额map
	private static concurrenthashmap<string,integer> moneymap=new concurrenthashmap<string,integer>();
	public static void main(string[] args) {
		lockpool lockpool=new lockpool();
		executorservice service = executors.newcachedthreadpool();
		service.execute(lockpool.new boss("u2"));
		service.execute(lockpool.new boss("u1"));
		service.execute(lockpool.new boss("u1"));
		service.execute(lockpool.new boss("u3"));
		service.execute(lockpool.new boss("u2"));
		service.execute(lockpool.new boss("u2"));
		service.execute(lockpool.new boss("u3"));
		service.execute(lockpool.new boss("u2"));
		service.execute(lockpool.new boss("u2"));
		service.execute(lockpool.new boss("u4"));
		service.execute(lockpool.new boss("u2"));
		service.shutdown();
	}
	class boss implements runnable{
		private string userid;
		boss(string userid){
			this.userid=userid;
		}
		@override
		    public void run() {
			addmoney(userid);
		}
	}
	public static void addmoney(string userid){
		object obj=usermap.get(userid);
		if(obj==null){
			obj=new object();
			usermap.put(userid,obj);
		}
		//obj是与具体某个用户绑定,这里应用了synchronized(obj)的小技巧,而不是同步当前整个对象
		synchronized (obj) {
			try {
				system.out.println("-------sleep4s--------"+userid);
				thread.sleep(4000);
				system.out.println("-------awake----------"+userid);
			}
			catch (interruptedexception e) {
				e.printstacktrace();
			}
			if(moneymap.get(userid)==null){
				moneymap.put(userid,1);
			} else{
				moneymap.put(userid, moneymap.get(userid)+1);
			}
			system.out.println(userid+"-------moneny----------"+moneymap.get(userid));
		}
	}
}

 测试结果:

-------sleep4s--------u2
-------sleep4s--------u1
-------sleep4s--------u3
-------sleep4s--------u4
-------awake----------u2
-------awake----------u3
-------awake----------u1
u2-------moneny----------1
u1-------moneny----------1
-------sleep4s--------u1
u3-------moneny----------1
-------sleep4s--------u2
-------sleep4s--------u3
-------awake----------u4
u4-------moneny----------1
-------awake----------u1
u1-------moneny----------2
-------awake----------u3
u3-------moneny----------2
-------awake----------u2
u2-------moneny----------2
-------sleep4s--------u2
-------awake----------u2
u2-------moneny----------3
-------sleep4s--------u2
-------awake----------u2
u2-------moneny----------4
-------sleep4s--------u2
-------awake----------u2
u2-------moneny----------5
-------sleep4s--------u2
-------awake----------u2
u2-------moneny----------6

测试结果来看,只有相同userid的线程才会互斥,同步等待;不同userid的线程没有同步

总结

以上就是本文关于java基于concurrenthashmap设计细粒度实现代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:、等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网