zoukankan      html  css  js  c++  java
  • 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行),其他线程在读取数据的时候上读锁后互不影响。这样可以提高读取效率。



  • 相关阅读:
    HDU 6034
    HDU 6047
    CodeForces 830B
    HDU 4972
    HDU 4408
    CodeForces 788B
    CodeForces 788A
    CodeForces 792C
    uva 1658 Admiral 最小费最大流
    hdu 5391 Zball in Tina Town 威尔逊定理
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468794.html
Copyright © 2011-2022 走看看