多线程-读写锁(1)

多线程读写锁关系

读--读   并行 ,不阻塞

读--写  串行,阻塞

写--写  串行,阻塞

package chapter3;

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Created by 13 on 2017/5/5.
 */
public class ReadWriteLockDemo {
    private static Lock lock = new ReentrantLock();
    private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    private static Lock readLock = reentrantReadWriteLock.readLock();
    private static Lock writeLock = reentrantReadWriteLock.writeLock();
    private int value;

    public Object handleRead(Lock lock) throws InterruptedException {
        
        while(true){//此处添加while循环,确保一直循环读,程序的效果应该每次读都是是18个线程并行读
            try {
                lock.lock();
                Thread.sleep(1000);//模拟读操作
                System.out.println(Thread.currentThread().getName()+"读操作:" + value);
//                return value;
            } finally {
                lock.unlock();
            }
        }
        
    }

    public void handleWrite(Lock lock, int index) throws InterruptedException {
      
        while (true) {//循环写,2个写线程,线程1写的时候线程2等待,也可能线程1一直写,看谁先获得锁。
             try {          //运行的结果是线程1先获得锁,进行写操作345后释放锁,然后线程2此刻获得锁,进行写操作426,然后释放锁
                lock.lock();//线程2后续几次又分别获得写锁,一直写426.接着在线程2释放锁的时候,读锁获得了资源,进行读(18个并行)
                            //读的过程中,不能进行写操作,读写是串行互斥的。
                Thread.sleep(1000);//模拟写操作
                value = index;
                System.out.println(Thread.currentThread().getName()+"写操作:" + value);
            } finally {
                lock.unlock();
            }
        }
   

    }

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

        Runnable readRunnable = new Runnable() {
            @Override
            public void run() {
                //分别使用两种锁来运行,性能差别很直观的就体现出来,使用读写锁后读操作可以并行,节省了大量时间
                try {
                    demo.handleRead(readLock);
                    //demo.handleRead(lock);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        };

        Runnable writeRunnable = new Runnable() {
            @Override
            public void run() {
                //分别使用两种锁来运行,性能差别很直观的就体现出来
                try {
                    demo.handleWrite(writeLock, new Random().nextInt(1000));
                    //demo.handleWrite(lock, new Random().nextInt(100));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        };
        for (int i = 0; i < 18; i++) {
            new Thread(readRunnable).start();//18个读锁是并行的
        }
        for (int i = 18; i < 20; i++) {
            new Thread(writeRunnable).start();//两个写锁匙串行的。读与写之间也是串行的
        }
    }
}

运行结果如下:

Thread-1读操作:0
Thread-0读操作:0
Thread-8读操作:0
Thread-6读操作:0
Thread-3读操作:0
Thread-7读操作:0
Thread-2读操作:0
Thread-4读操作:0
Thread-5读操作:0
Thread-10读操作:0
Thread-12读操作:0
Thread-11读操作:0
Thread-9读操作:0
Thread-13读操作:0
Thread-16读操作:0
Thread-15读操作:0
Thread-14读操作:0
Thread-17读操作:0 //18次并行读操作

Thread-18写操作:345 //写线程1获得写锁
Thread-19写操作:426 //写线程2获得写锁
Thread-19写操作:426 //写线程2获得写锁
Thread-19写操作:426
Thread-19写操作:426
Thread-19写操作:426
Thread-19写操作:426 //写线程2获得写锁

Thread-0读操作:426 //读线程获得读锁
Thread-4读操作:426
Thread-3读操作:426
Thread-7读操作:426
Thread-17读操作:426
Thread-13读操作:426
Thread-11读操作:426
Thread-1读操作:426
Thread-6读操作:426
Thread-8读操作:426
Thread-2读操作:426
Thread-5读操作:426
Thread-12读操作:426
Thread-10读操作:426
Thread-9读操作:426
Thread-15读操作:426
Thread-16读操作:426
Thread-14读操作:426 //读线程获得读锁

Thread-18写操作:345 //写线程1获得写锁
Thread-18写操作:345 
Thread-18写操作:345
Thread-18写操作:345
Thread-18写操作:345

原文地址:https://www.cnblogs.com/Andrew520/p/8886713.html