Java线程学习之读写锁

读写锁:

  因为读写锁分为读锁和写锁,读因为不会对数据造成改变,所以两个或多个线程的读之间不需要添加锁。而写锁不同,因为写对数据会进行改变,所以 写与写之间,读与写之间都需要加锁控制。而在重入锁中,读与读之间也会使用互斥锁,造成等待时间延长。这样的话读写锁的使用场景也就出来了,读写锁适用于读操作远比写操作的次数,这样可以提升系统性能。

例子:

package com.example.demo.bingfa;

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

public class ReadWriteLockDemo {
    public static Lock lock = new ReentrantLock();
    public static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private static Lock readLock = readWriteLock.readLock();
    public static Lock writeLock = readWriteLock.writeLock();
    private int value;
    public static long readTime;
    public static  long writeTime;
    public static void main(String[] args) throws InterruptedException {
        final ReadWriteLockDemo demo = new ReadWriteLockDemo();
        Runnable readRunnale = new Runnable() {
            @Override
            public void run() {
                try {
                    //此处传入的是读锁,如果换成重入锁,运行结果会变化很大
                    demo.handleRead(readLock);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        Runnable writeRunnale = new Runnable() {
            @Override
            public void run() {
                try {
                    //此处传入的是写锁,如果换成重入锁,将会改变
                    demo.handleWrite(writeLock, new Random().nextInt());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        long start=System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            new Thread(readRunnale).start();
        }
        for (int i = 10; i < 20; i++) {
                new Thread(writeRunnale).start();
        }
        //让主线程等待一段时间,确保子线程均已执行完毕
        Thread.sleep(30000);
        System.out.println("读操作耗时:" +(readTime-start)+"        写操作耗时"+(writeTime-start));
    }

    /**
     * 写操作处理,因为写与写之间是互斥的 ,所以每个写的线程都需要等待获得锁
     * @param writeLock
     * @param i
     * @throws InterruptedException
     */
    private void handleWrite(Lock writeLock, int i) throws InterruptedException {
        try {
            writeLock.lock();
            Thread.sleep(1000);
            value = i;
        } finally {
            writeLock.unlock();
            writeTime=System.currentTimeMillis();
        }
    }

    /**
     * 因为读与读之间不是互斥的所以读与读是可以并行的
     * @param readLock
     * @return
     * @throws InterruptedException
     */
    private int handleRead(Lock readLock) throws InterruptedException {
        try {
            readLock.lock();
            Thread.sleep(1000);
            return value;
        } finally {

            readLock.unlock();
            readTime=System.currentTimeMillis();
        }
    }
}

 

posted on 2022-04-22 16:25  山水爱恋  阅读(82)  评论(0编辑  收藏  举报