1.ReentrantLock、Synchronized都是排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时刻允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。
1.由于读和读之间并不对数据的完整性造成破坏,所以读写锁允许多个线程同时读,但是读写操作、写写操作之间仍然要相互等待和持有锁的。而重入锁在读和读互斥等待浪费了时间。
1)读写锁使用方法:
ReadWriterLock rwlock = new ReentranReadWriterLock();
rwlock.writeLock().lock(); //获得写入操作的锁,并上锁
//写入操作执行
rwlock.writeLock().unlock(); //获得写入操作的锁,并解锁
rwlock.readLock().lock(); //获取读取操作的锁,并上锁
//读取操作执行
rwlock.readLock().unlock(); //获取读取操作的锁,并解锁
博客https://blog.youkuaiyun.com/lzm1340458776/article/details/27964243中例子看到读写锁运行效果。
class ReadWrite {
//共享数据,只能一个线程写数据,可以多个线程读数据
private Object data = null;
//创建一个读写锁
ReadWriteLock rwlock = new ReentrantReadWriteLock();
Lock r = rwlock.readLock(); //读锁
Lock w = rwlock.writeLock(); //写锁
public void get() {
r.lock(); //读上锁
try {
System.out.println(Thread.currentThread().getName() + "**准备读数据!");
Thread.sleep((long) (Math.random() * 1000)); //模拟读操作
System.out.println(Thread.currentThread().getName() + "---------读出的数据为 :" + data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
r.unlock();
}
}
public void put(Object data) {
w.lock(); //写上锁
try {
System.out.println(Thread.currentThread().getName() + " +++++++准备写数据!");
Thread.sleep((long) (Math.random() * 1000)); //模拟写操作
this.data = data;
System.out.println(Thread.currentThread().getName() + " ........写入的数据: " + data);
} catch (Exception e) {
e.printStackTrace();
} finally {
w.unlock();
}
}
}
public class ReentrantReadWriterLockTest{
public static void main(String[] args) {
final ReadWrite readWrite = new ReadWrite();
for (int i = 0; i < 3; i++) { //创建并启动3个读线程
new Thread(new Runnable() {
@Override
public void run() {
readWrite.put(new Random().nextInt(8)); //随机写入一个数据
}
}).start();
}
for(int i=0;i<9;i++){ //创建并启动了9个写线程
new Thread(new Runnable() {
@Override
public void run() {
readWrite.get();
}
}).start();
}
}
}
部分输出:
Thread-0 +++++++准备写数据!
Thread-0 ........写入的数据: 7
Thread-1 +++++++准备写数据!
Thread-1 ........写入的数据: 6
Thread-2 +++++++准备写数据!
Thread-2 ........写入的数据: 3
Thread-5**准备读数据!
Thread-4**准备读数据!
Thread-3**准备读数据!
说明:可以看出:看出输出中准备写数据和写入的数据时成对出现的,印证了当获取写锁后,其他线程对于读锁和写锁的获取均被阻塞。