并发编程-concurrent指南-ReadWriteLock-ReentrantReadWriteLock(可重入读写锁)

几个线程都申请读锁,都能获取

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
 * 几个线程都申请读锁,都能用
 */
public class MainRead {
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

    public static void main(String[] args) {
        final MainRead main = new MainRead();

        new Thread(new Runnable() {
            @Override
            public void run() {
                main.insert(Thread.currentThread());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                main.insert(Thread.currentThread());
            }
        }).start();
    }

    /**
     * 几个线程都申请读锁,都能用
     * @param thread
     */
    public void insert(Thread thread){
        reentrantReadWriteLock.readLock().lock();
        try{
            for(int i=0;i<5;i++){
                System.out.println(thread.getName()+":"+i+",进行读操作");
                TimeUnit.SECONDS.sleep(1);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println(thread.getName()+"释放读锁");
            reentrantReadWriteLock.readLock().unlock();
        }
    }
}

结果:

Thread-0:0,进行读操作
Thread-1:0,进行读操作
Thread-1:1,进行读操作
Thread-0:1,进行读操作
Thread-0:2,进行读操作
Thread-1:2,进行读操作
Thread-0:3,进行读操作
Thread-1:3,进行读操作
Thread-0:4,进行读操作
Thread-1:4,进行读操作
Thread-0释放读锁
Thread-1释放读锁

几个线程,一个线程抢占了读锁,别的线程想用写锁时,需要等待读锁完成才行

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
 * 几个线程,一个线程抢占了读锁,别的线程想用写锁时,需要等待读锁完成才行
 */
public class MainWrite {
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

    public static void main(String[] args) {
        final MainWrite main = new MainWrite();

        new Thread(new Runnable() {
            @Override
            public void run() {
                main.read(Thread.currentThread());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                main.write(Thread.currentThread());
            }
        }).start();
    }

    public void read(Thread thread){
        reentrantReadWriteLock.readLock().lock();
        try{
            display(thread);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println(thread.getName()+"释放读锁");
            reentrantReadWriteLock.readLock().unlock();
        }
    }

    public void write(Thread thread){
        reentrantReadWriteLock.writeLock().lock();
        try{
            display(thread);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println(thread.getName()+"释放写锁");
            reentrantReadWriteLock.writeLock().unlock();
        }
    }

    public void display(Thread thread) throws InterruptedException {
        for(int i=0;i<5;i++){
            System.out.println(thread.getName()+":"+i+",进行操作");
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

结果:

Thread-0:0,进行操作
Thread-0:1,进行操作
Thread-0:2,进行操作
Thread-0:3,进行操作
Thread-0:4,进行操作
Thread-0释放读锁
Thread-1:0,进行操作
Thread-1:1,进行操作
Thread-1:2,进行操作
Thread-1:3,进行操作
Thread-1:4,进行操作
Thread-1释放写锁

源码地址:https://github.com/qjm201000/concurrent_reentrantReadWriteLock.git

这样就大大提升了读操作的效率。

  不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。

  如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。

原文地址:https://www.cnblogs.com/qjm201000/p/10178010.html