Java读写锁的使用

Java并行编程时经常使用关键字synchronized来实现同步访问,但是很多情况下synchronized会影响执行效率

例如:当多线程读写文件时,读操作之间并不冲突,但是synchronized会使所有的读操作都同步执行而影响效率
这种情况下最好的解决方法是使用java.util.concurrent.locks下提供的读写锁ReentrantReadWriteLock。这个lock类的读锁是可重入的,只有当有线程获取写锁时才会同步线程


为了学习ReentrantReadWriteLock的使用,写了一个测试类TestMap。通过对静态私有变量map进行get/put操作,测试读写锁的使用。

public class TestMap {

	private static final Map<String, String> map;
	private static final ReentrantReadWriteLock readWriteLock;

	static {
		map = new HashMap<String, String>();
		readWriteLock = new ReentrantReadWriteLock();
	}

	public static String get(String key) {
		try {
                        // 读取时使用读锁
                        readWriteLock.readLock().lock();
			System.out.println(Thread.currentThread().getId()
					+ " get read lock.");
			if (map.containsKey(key)) {
				return map.get(key);
			}
			return "";
		} finally {
			readWriteLock.readLock().unlock();
			System.out.println(Thread.currentThread().getId()
					+ " release read lock.");
		}
	}

	public static void set(String key, String value) {
		try {
                        // 写入时使用写锁
                        readWriteLock.writeLock().lock();
			System.out.println(Thread.currentThread().getId()
					+ " get write lock.");
			map.put(key, value);
		} finally {
			readWriteLock.writeLock().unlock();
			System.out.println(Thread.currentThread().getId()
					+ " release write lock.");
		}
	}
}
要注意锁的释放一定要写在finally代码块中。因为与synchronized不同,发生异常时锁并不会自动被释放

以下是调用TestMap进行测试的代码

public class MapRunable implements Runnable {
	@Override
	public void run() {
		TestMap.set(String.valueOf(Thread.currentThread().getId()), Thread
				.currentThread().getName());
		TestMap.get(String.valueOf(Thread.currentThread().getId()));
	}
}

public static void main(String[] args){
		Thread thread1 = new Thread(new MapRunable());
		Thread thread2 = new Thread(new MapRunable());
		Thread thread3 = new Thread(new MapRunable());
		Thread thread4 = new Thread(new MapRunable());
		Thread thread5 = new Thread(new MapRunable());
		thread1.start();
		thread2.start();
		thread3.start();
		thread4.start();
		thread5.start();
	}

执行结果为:

9 get write lock.
9 release write lock.
13 get write lock.
13 release write lock.
10 get write lock.
10 release write lock.
12 get write lock.
12 release write lock.
11 get write lock.
11 release write lock.
9 get read lock.
10 get read lock.
10 release read lock.
11 get read lock.
11 release read lock.
12 get read lock.
13 get read lock.
12 release read lock.
9 release read lock.
13 release read lock.

可以看出,当获得写锁时,只能等待该线程将写锁释放。但是获得读锁时,别的线程仍然可以获得读锁。

如果读操作也需要同步,则需要使用ReentrantLock

关于锁tryLock,lockInterruptibly的使用此处不再赘述了

推荐一篇学习过的文章,有比较详细的说明:http://www.cnblogs.com/dolphin0520/p/3923167.html


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值