java多线程编程之读写锁设计高性能缓存器

解决多线程线程安全问题的主要方法是通过加锁的方式来实现,当多个线程对某个变量进行读取或写入的时候通过加锁来限定只有当前获取锁权限的线程才可以对数据进行读写,当该线程访问完毕释放锁之后其他阻塞线程才拥有访问权限,当下一个线程得到执行权限的时候同样进行上述操作步骤。而实现加锁的方式最简单的有两种,一个是通过关键字synchronized来对整个方法或部分代码块进行加锁,另外一种是用Lock对象来实现线程互斥,保证线程安全。对于一般系统来讲,加锁的方式在很大程度上已经满足了系统需要,但是当系统面临高并发请求的时候这种加锁方式显然不能解决系统效率问题,为此通过更高性能的读写锁并配合缓存系统解决性能问题成为了首选方案。

为什么会出现读写锁?为什么使用读写锁的性能会更高一些?这是因为在传统的synchronized关键字或Lock对象加锁的时候是不区分是读操作还是锁操作的,只要有线程进入之后就会对该段代码进行锁定直到线程释放锁,考虑一下在具体的应用环境中通常出现最多的并不是大量的写操作,而是读操作,如果仅仅是读操作不涉及到共享数据的写操作是没有必要进行加锁行为的,一旦加了锁之后大量的读操作只能按队列顺序依次读取,这就好比是双车道的马路加锁之后变成了单车道,会造成不必要的性能上的损失。但是我们又不得不考虑大量读操作中夹杂写操作的情况,一旦未对写操作进行加锁,又很可能造成线程上的不安全问题。所以为了兼顾系统性能和线程安全,读写锁应运而生。由于读锁是排写锁操作的,但是读锁并不排读锁操作,多个读锁可以并发不阻塞所以它可以很好的应对高并发的读操作,同时写锁又是拍写锁操作和排读写操作的,即当某个线程加上读锁之后,在该锁释放之前其他线程是不能进行读操作更不能进行写操作的,这样就解决了线程的安全问题。下面通过实例介绍一下如何通过读写锁设计高性能的缓存系统。

public class CacheContainer {

	private Map<String, Object> cache = new HashMap<String, Object>();

	private ReadWriteLock rwl = new ReentrantReadWriteLock();
	public  Object getData(String key){
		rwl.readLock().lock();
		Object value = null;
		try{
			value = cache.get(key);
			if(value == null){
				rwl.readLock().unlock();
				rwl.writeLock().lock();
				try{
					if(value==null){
						value = "test";//查询数据库操作后更新数据
                                                cache.put(key,value);
                                        }
				}finally{
					rwl.writeLock().unlock();
				}
				rwl.readLock().lock();
			}
		}finally{
			rwl.readLock().unlock();
		}
		return value;
	}
}

分析上面缓存器代码可以看出当多个线程从缓存中取数据的时候首先加上读锁,这样可以保证多个线程之间并发的执行读操作,然后根据key值从试图从容器中获取对应的value,当获取的value值存在的时候将该值返回,这种情况相当于没有加锁。但是当某个线程首先到达读操作的时候发现value没有对应的值,此时需要进行的是从数据库中读取数据并将该数据放入缓存中,在读数据库并更新数据的时候就必须需要加写锁来保证在写操作的排他性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值