有时候我们需要有这样的需求:
对于同一个文件进行读和写操作,普通的锁是互斥的,这样读的时候会加锁,只能单线程的读,我们希望多线程的进行读操作,并且读的时候不能进行写操作,写的时候不能进行读操作,也就是:“读读不互斥”,“读写互斥”,“写写互斥”这个时候就需要用的jdk听的“读写锁了。
ReentrantReadWriteLock:读写锁,分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,由JVM控制。
测试代码如下:
import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 读写锁 * "写写"和“读写”都是互斥 * “读读”不需要互斥 * Created by gan on 2019/5/19 16:53. */ public class ReadWriteLockDemo { private static int number = 0; //初始化读写锁 private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public static void main(String[] args) { new Thread(() -> { //用100个线程去读 for (Integer i = 0; i < 100; i++) { final int j = i; new Thread(() -> { read(); }, i.toString()).start(); } }).start(); new Thread(() -> { //用100个线程去写 for (Integer i = 0; i < 100; i++) { final int j = i; new Thread(() -> { write(j); }, i.toString()).start(); } }).start(); } /** * 读方法 */ public static void read() { lock.readLock().lock(); //获取读锁 try { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "读读读-----" + number); } } catch (Exception e) { } finally { lock.readLock().unlock(); //finally块里面释放读锁 } } public static void write(int num) { lock.writeLock().lock(); //获取写锁 try { number = num; for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "写写写++++++" + number); } } catch (Exception e) { } finally { lock.writeLock().unlock(); //finally块里面释放写锁 } } }
我们期望的结果是在读线程操作方法read()打印时候是“乱序的”,也就是其他读线程也会交替的打印读操作。 但是当写线程操作方法write()执行的时候必须是等待这个方法打印完毕,其他读或者写线程才能执行,也就是说些write()方法进行打印的时候必须是当前一个写线程连续的打印完毕,中间不会被其他读或者写线程打断。 运行结果如下: