如果说ReetrantLock是一种互斥锁的话,那么还有一种锁叫读写锁ReadWriteLock。通俗点说,互斥锁相当一个线程持有这个锁以后,其他任何线程都不能再获取这个锁了,但可以设想2个线程对一个公共内容读写的场景,如果一个线程对公共内容进行写操作,那么另一个线程这不能读也不能写这个内容,但如果一个线程对公共内容进行读操作,那实际应该允许另个一线程对该内容进行读操作,但禁止写操作,即读-读允许,读-写互斥,写-写互斥,ReadWriteLock就解决这个问题。
我们分别建立2个读写类来说明效果
public class ReadWriteLockDemo {
static ReadWriteLock lock = new ReentrantReadWriteLock();
static class Read implements Runnable{
private String name;
public Read(String name){
this.name = name;
}
@Override
public void run() {
lock.readLock().lock();
try {
for (int i = 0; i < 5; i++) {
System.out.println(name + " read content " + i);
}
} finally {
lock.readLock().unlock();
}
}
}
static class Write implements Runnable{
private String name;
public Write(String name){
this.name = name;
}
@Override
public void run() {
lock.writeLock().lock();
try {
for (int i = 0; i < 5; i++) {
System.out.println(name + " write content " + i);
}
} finally {
lock.writeLock().unlock();
}
}
}
public static void main(String[] args) {
new Thread(new Read("t1")).start();
new Thread(new Read("t2")).start();
}
}
建立好读写类后,我们启动2个线程进行并发读,控制台输出如下:
t1 read content 0
t2 read content 0
t1 read content 1
t2 read content 1
t1 read content 2
t2 read content 2
t1 read content 3
t2 read content 3
t1 read content 4
t2 read content 4
可见读线程之间相互不排斥。
如果换成一个读线程和一个写,线程
new Thread(new Read(“t1”)).start();
new Thread(new Write(“t2”)).start();
那么控制台输出如下:
t1 read content 0
t1 read content 1
t1 read content 2
t1 read content 3
t1 read content 4
t2 write content 0
t2 write content 1
t2 write content 2
t2 write content 3
t2 write content 4
可以看出这里的读写就变成了串行执行,如果启动2个写线程,也会是串行的效果