我们都知道锁分共享锁和排他锁,实际使用中我们一般将锁机制分为读和写两种场景,即我们期望写入排他,读取共享。Java由此提供了包转后的读写锁工具类。
//创建对象
ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
//创建写锁
readWriteLock.writeLock().lock();
//解锁
readWriteLock.writeLock().unlock();
//创建读锁
readWriteLock.readLock().lock();
特点
- 读锁可以访问,操作资源,而写锁将阻塞其他线程
- 加入读锁无法加锁
- 并发性更好
- 可重入
ps :可重入锁是指该线程a获取锁,可重新申请获取锁
重入锁的介绍
package day2.读写锁;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Book {
private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
int num=10;
void buy() throws InterruptedException {
readWriteLock.writeLock().lock();
System.out.println("正在清算 购入图书"+Thread.currentThread().getName()+" 当前 "+num);
TimeUnit.SECONDS.sleep(3);
num = num +1;
readWriteLock.writeLock().unlock();
}
void find(){
readWriteLock.readLock().lock();
System.out.println("查看当前图书"+Thread.currentThread().getName()+"当前 "+num);
readWriteLock.readLock().unlock();
}
void sale() throws InterruptedException {
readWriteLock.writeLock().lock();
System.out.println("当前可售卖图书 "+Thread.currentThread().getName()+" 当前 "+num);
if(num>=1){
num = num -1;}
readWriteLock.writeLock().unlock();
}
}
package day2.读写锁;
import java.util.concurrent.TimeUnit;
public class test {
public static void main(String args[]) throws InterruptedException {
Book book=new Book();
new Thread(()->{
for(int i=0;i<=100;i++){
book.find();}
}).start();
new Thread(()->{
while(true){
try {
book.find();
book.sale();
//TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(()->{
while(true){
try {
book.find();
book.buy();
// TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(()->{
while(true){
try {
book.find();
book.buy();
// TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}}