Java多线程编程之读写锁【ReentrantReadWriteLock】

有时候我们需要有这样的需求:
        对于同一个文件进行读和写操作,普通的锁是互斥的,这样读的时候会加锁,只能单线程的读,我们希望多线程的进行读操作,并且读的时候不能进行写操作,写的时候不能进行读操作,也就是:“读读不互斥”,“读写互斥”,“写写互斥”这个时候就需要用的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()方法进行打印的时候必须是当前一个写线程连续的打印完毕,中间不会被其他读或者写线程打断。 运行结果如下:

原文地址:https://www.cnblogs.com/ganbo/p/10889958.html