【Java】ReadWriteLock & ReentrantReadWriteLock
ReadWriteLock
ReadWriteLock
也是一个接口,在它里面只定义了两个方法:
public interface ReadWriteLock {
Lock readLock();
Lock writeLock();
}
readLock()
用来获取读锁,writeLock()
用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作。
ReentrantReadWriteLock
ReentrantReadWriteLock
是ReadWriteLock
接口的实现,里面提供了很多丰富的方法,不过最主要的有两个方法:readLock()
和writeLock()
用来获取读锁和写锁。
代码示例
- 假如有多个线程要同时进行读操作的话,先看一下
synchronized
达到的效果
public class SynchronizedReadWriteTest implements Runnable {
@Override
public synchronized void run() {
Thread currentThread = Thread.currentThread();
long start = System.currentTimeMillis();
int i = 0;
while (System.currentTimeMillis() - start <= 1) {
i++;
if (i % 4 == 0) {
System.out.println(currentThread.getName() + "正在进行写操作");
} else {
System.out.println(currentThread.getName() + "正在进行读操作");
}
}
System.out.println(currentThread.getName() + "读写操作完毕");
}
public static void main(String[] args) {
SynchronizedReadWriteTest test = new SynchronizedReadWriteTest();
Thread thread1 = new Thread(test, "thread1");
Thread thread2 = new Thread(test, "thread2");
thread1.start();
thread2.start();
}
}
一个线程又要读又要写,用
synchronized
来实现的话,读写操作都只能锁住后一个线程一个线程地进行
- 改成用读写锁的话
public class ReentrantReadWriteLockTest implements Runnable {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void get(Thread thread) {
lock.readLock().lock();
try {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start <= 1) {
System.out.println(thread.getName() + "正在进行读操作");
}
System.out.println(thread.getName() + "读操作完毕");
} finally {
lock.readLock().unlock();
}
}
public void write(Thread thread) {
lock.writeLock().lock();
try {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start <= 1) {
System.out.println(thread.getName() + "正在进行写操作");
}
System.out.println(thread.getName() + "写操作完毕");
} finally {
lock.writeLock().unlock();
}
}
@Override
public void run() {
Thread currentThread = Thread.currentThread();
get(currentThread);
write(currentThread);
}
public static void main(String[] args) {
ReentrantReadWriteLockTest test = new ReentrantReadWriteLockTest();
Thread thread1 = new Thread(test, "thread1");
Thread thread2 = new Thread(test, "thread2");
thread1.start();
thread2.start();
}
}
如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。但是读操作还是可以继续进行。
如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
评论区