ReadWriteLock 读写锁 又叫排他锁
如果使用互斥锁,一个线程在读,其他线程也不能读也不能写
换成读写锁的时候,读线程是读锁,写线程是写锁,写锁是排他的
在多线程大大提高效率,当一个线程在读的时候,其他线程也可以进来继续读
import java.util.Random;
import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class T10_TestReadWriteLock {static Lock lock = new ReentrantLock();private static int value;static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();static Lock readLock = readWriteLock.readLock();static Lock writeLock = readWriteLock.writeLock();public static void read(Lock lock) {try {lock.lock();Thread.sleep(1000);System.out.println("read over!");//模拟读取操作} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public static void write(Lock lock, int v) {try {lock.lock();Thread.sleep(1000);value = v;System.out.println("write over!");//模拟写操作} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public static void main(String[] args) {//Runnable readR = ()-> read(lock);Runnable readR = ()-> read(readLock);//Runnable writeR = ()->write(lock, new Random().nextInt());Runnable writeR = ()->write(writeLock, new Random().nextInt());for(int i=0; i<18; i++) new Thread(readR).start();for(int i=0; i<2; i++) new Thread(writeR).start();}
}
使用ReentrantLock 20s
使用ReentrantReadWriteLock 2s
目前有 18 个线程执行读操作,每个读操作需要 1 秒钟执行,同时有 2 个线程执行写操作,每个写操作也需要 1 秒钟执行。
因为读操作是共享锁(读锁),多个线程可以同时获得读锁,但写操作是独占锁(写锁),只有一个线程能获得写锁,其他线程需要等待。
根据代码逻辑,18 个读线程并发执行,每个读线程需要 1 秒执行完毕,因为读操作是并发执行的,所以整体读操作的时间是 1 秒。
同时,2 个写线程需要依次获取写锁执行写操作,每个写线程也需要 1 秒执行完毕。由于写操作是独占锁,所以第一个写线程执行完毕后,第二个写线程才能获取到写锁执行写操作。
因此,整体来看,读线程总共需要 1 秒,写线程总共需要 2 秒(1 秒执行写操作,1 秒等待另一个写线程执行完毕),所以整个程序执行的时间大约是 2 秒左右。