多线程-ReentrantReadWriteLock
ReentrantLock具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()方法后面的任务。这样做虽然保证了实例变量的线程安全,但效率却是非常低下的。JDK中提供了一个读写锁ReentrantReadWriteLock,使用它可以加快运行效率,在某些不需要操作实例变量的方法中,完全可以使用读写锁ReentrantReadWriteLock来提升该方法的代码运行速度。
读写锁有两个锁:读锁和写锁,读锁也称为共享锁,写锁称为排他锁。也就是多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。
package org.github.lujiango; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Test09 { static class Service { private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void read() { try { lock.readLock().lock(); System.out.println("get read lock: " + Thread.currentThread().getName()); Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } finally { lock.readLock().unlock(); } } public void write() { try { lock.writeLock().lock(); System.out.println("get write lock: " + Thread.currentThread().getName()); Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } finally { lock.writeLock().unlock(); } } } static class ThreadReader extends Thread { private Service service; public ThreadReader(Service service) { this.service = service; } @Override public void run() { service.read(); } } static class ThreadWriter extends Thread { private Service service; public ThreadWriter(Service service) { this.service = service; } @Override public void run() { service.write(); } } public static void main(String[] args) { Service service = new Service(); // (1) 读读 ThreadReader r1 = new ThreadReader(service); ThreadReader r2 = new ThreadReader(service); r1.start(); r2.start(); // (2) 写写 ThreadWriter w1 = new ThreadWriter(service); ThreadWriter w2 = new ThreadWriter(service); w1.start(); w2.start(); } }
总结:读写,写读,写写都是互斥的;而读读是异步的,非互斥的。