并发编程-concurrent指南-ReadWriteLock-ReentrantReadWriteLock(可重入读写锁)
几个线程都申请读锁,都能获取:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 几个线程都申请读锁,都能用
*/
public class MainRead {
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
public static void main(String[] args) {
final MainRead main = new MainRead();
new Thread(new Runnable() {
@Override
public void run() {
main.insert(Thread.currentThread());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
main.insert(Thread.currentThread());
}
}).start();
}
/**
* 几个线程都申请读锁,都能用
* @param thread
*/
public void insert(Thread thread){
reentrantReadWriteLock.readLock().lock();
try{
for(int i=0;i<5;i++){
System.out.println(thread.getName()+":"+i+",进行读操作");
TimeUnit.SECONDS.sleep(1);
}
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println(thread.getName()+"释放读锁");
reentrantReadWriteLock.readLock().unlock();
}
}
}
结果:
Thread-0:0,进行读操作
Thread-1:0,进行读操作
Thread-1:1,进行读操作
Thread-0:1,进行读操作
Thread-0:2,进行读操作
Thread-1:2,进行读操作
Thread-0:3,进行读操作
Thread-1:3,进行读操作
Thread-0:4,进行读操作
Thread-1:4,进行读操作
Thread-0释放读锁
Thread-1释放读锁
几个线程,一个线程抢占了读锁,别的线程想用写锁时,需要等待读锁完成才行
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 几个线程,一个线程抢占了读锁,别的线程想用写锁时,需要等待读锁完成才行
*/
public class MainWrite {
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
public static void main(String[] args) {
final MainWrite main = new MainWrite();
new Thread(new Runnable() {
@Override
public void run() {
main.read(Thread.currentThread());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
main.write(Thread.currentThread());
}
}).start();
}
public void read(Thread thread){
reentrantReadWriteLock.readLock().lock();
try{
display(thread);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println(thread.getName()+"释放读锁");
reentrantReadWriteLock.readLock().unlock();
}
}
public void write(Thread thread){
reentrantReadWriteLock.writeLock().lock();
try{
display(thread);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println(thread.getName()+"释放写锁");
reentrantReadWriteLock.writeLock().unlock();
}
}
public void display(Thread thread) throws InterruptedException {
for(int i=0;i<5;i++){
System.out.println(thread.getName()+":"+i+",进行操作");
TimeUnit.SECONDS.sleep(1);
}
}
}
结果:
Thread-0:0,进行操作
Thread-0:1,进行操作
Thread-0:2,进行操作
Thread-0:3,进行操作
Thread-0:4,进行操作
Thread-0释放读锁
Thread-1:0,进行操作
Thread-1:1,进行操作
Thread-1:2,进行操作
Thread-1:3,进行操作
Thread-1:4,进行操作
Thread-1释放写锁
源码地址:https://github.com/qjm201000/concurrent_reentrantReadWriteLock.git
这样就大大提升了读操作的效率。
不过要注意的是,如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。
如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。


浙公网安备 33010602011771号