多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # ReadWriteLock ReadWriteLock也是一个接口,在它里面只定义了两个方法: ~~~ public interface ReadWriteLock { /** * Returns the lock used for reading. * * @return the lock used for reading. */ Lock readLock(); /** * Returns the lock used for writing. * * @return the lock used for writing. */ Lock writeLock(); } ~~~ 一个用来获取读锁,一个用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作。下面的ReentrantReadWriteLock实现了ReadWriteLock接口。 ## ReentrantReadWriteLock ReentrantReadWriteLock里面提供了很多丰富的方法,不过最主要的有两个方法:readLock()和writeLock()用来获取读锁和写锁。 下面通过几个例子来看一下ReentrantReadWriteLock具体用法。 假如有多个线程要同时进行读操作的话,用synchronized ~~~ package testThread; import java.util.concurrent.locks.ReentrantReadWriteLock; public class TestThread { private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); public static void main(String[] args) { final TestThread testThread = new TestThread(); new Thread() { public void run() { testThread.get(Thread.currentThread()); } }.start(); new Thread() { public void run() { testThread.get(Thread.currentThread()); } }.start(); } private synchronized void get(Thread thread) { long start = System.currentTimeMillis(); while (System.currentTimeMillis() - start <= 1) { System.out.println(thread.getName() + "正在进行读操作"); } System.out.println(thread.getName() + "读操作完毕"); } } ~~~ 这些线程是一次执行的 用读写锁的话: ~~~ package testThread; import java.util.concurrent.locks.ReentrantReadWriteLock; public class TestThread { private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); public static void main(String[] args) { final TestThread testThread = new TestThread(); new Thread() { public void run() { testThread.get(Thread.currentThread()); } }.start(); new Thread() { public void run() { testThread.get(Thread.currentThread()); } }.start(); } private void get(Thread thread) { rwl.readLock().lock(); try { long start = System.currentTimeMillis(); while (System.currentTimeMillis() - start <= 1) { System.out.println(thread.getName() + "正在进行读操作"); } System.out.println(thread.getName() + "读操作完毕"); } finally { rwl.readLock().unlock(); } } } ~~~ 说明thread1和thread2在同时进行读操作。 这样就大大提升了读操作的效率。 不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。 如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。 锁降级:写锁--没释放--可以降级到读锁 锁升级:读锁-没释放--可以升级到写锁 在分布式场景下,像读写锁这样的锁,加入不用锁降级的方式,可能会出现脏读的现象