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();
}
}
}
生于忧患,死于安乐