Android多线程研究(9)——读写锁

一、什么是锁

在Java的util.concurrent.locks包下有关于锁的接口和类如下:


先看一段代码:

package com.codeing.snail.test;


public class ReadWriteLockTest {
	public static void main(String[] args) {
		final Output output = new Output();
		new Thread(){
			public void run() {
				while(true){
					output.output("CodeingSnail");
				}
			};
		}.start();
		
		new Thread(){
			public void run() {
				while(true){
					output.output("阳光小强");
				}
			};
		}.start();
	}
	
	static class Output{
		public void output(String name){
			char[] arry = name.toCharArray();
			for(int i = 0; i < arry.length; i++){
				System.out.print(arry[i]);
			}
			System.out.println();
		}
	}
}

输出的结果如下:

如果我们想让“CodeingSnail"和“阳光小强"两个字符串都能完整输出,就需要使用synchronized关键字将输出部分声明,如下:

		public synchronized void output(String name){
			char[] arry = name.toCharArray();
			for(int i = 0; i < arry.length; i++){
				System.out.print(arry[i]);
			}
			System.out.println();
		}

其实,除了synchronized关键字之外,还可以使用锁(Lock)来实现同步。

		ReentrantLock lock = new ReentrantLock();
		public void output(String name){
			lock.lock();
			try{
				char[] arry = name.toCharArray();
				for(int i = 0; i < arry.length; i++){
					System.out.print(arry[i]);
				}
				System.out.println();
			}finally{
				lock.unlock();
			}
		}
上面代码使用try...finally语句块是为了防止出现异常执行不到unlock方法,ReentrantLock是Lock的实现类,Lock的作用和synchronized类似,但更加面向对象,要实现同步就必须使用同一个lock对象。

二、什么是读写锁

读写锁、分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。下面我们来看一下API文档中的一个缓存器的例子:
	class CachedData {
		Object data;
		volatile boolean cacheValid;
		final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

		void processCachedData() {
		     rwl.readLock().lock();
		     if (!cacheValid) {
		        // Must release read lock before acquiring write lock
		        rwl.readLock().unlock();
		        rwl.writeLock().lock();
		        try {
		          // Recheck state because another thread might have
		          // acquired write lock and changed state before we did.
		          if (!cacheValid) {
		            data = ...
		            cacheValid = true;
		          }
		          // Downgrade by acquiring read lock before releasing write lock
		          rwl.readLock().lock();
		        } finally {
		          rwl.writeLock().unlock(); // Unlock write, still hold read
		        }
		     }

		     try {
		       use(data);
		     } finally {
		       rwl.readLock().unlock();
		     }
	     }
	}
假如有多个线程来读取数据,第一个线程进来先上一把写锁进行数据写入(先释放读锁),写入完成后将写锁降级为读锁(第15行),其他线程在读取数据的时候上读锁后互不影响。这样可以提高读取效率。



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。