Java多线程学习记录(二)
读写锁
伪代码
一个通用的读写锁的伪代码如下所示
count_mutex = mutex_init();
write_mutex = mutex_init();
read_count = 0;
void read_lock {
lock(count_mutex);
read_count++;
if (read_count == 1) {
lock(write_mutex);
}
unlock(count_mutex);
}
void read_unlock {
lock(count_mutex);
read_count--;
if (read_count == 0) {
unlock(write_mutex);
}
unlock(count_mutex);
}
void write_lock {
lock(write_mutex);
}
void write_unlock {
unlock(write_mutex);
}
void read_lock {
lock(count_mutex);
read_count++;
if (read_count == 1) {
lock(write_mutex);
}
unlock(count_mutex);
}
lock(count_mutex)
的主要作用是保证read_count的计数访问
当read_count 是1的时候,锁住写者
void read_unlock {
lock(count_mutex);
read_count--;
if (read_count == 0) {
unlock(write_mutex);
}
unlock(count_mutex);
}
与上面的操作相反,如果当read_count-- 之后read_count 是0的时候,说明本线程是最后一位读者,所以在解锁读者锁之前要解锁写者锁。
读写锁的特性
一般来说,读取一个资源的并发操作由以下三个:
读读
读写
写写
假设只使用互斥锁的话,以上三个操作都会被阻塞,读写锁实际上就是为了解决这个问题,在大部分资源并发的操作下,操作1实际上是最普遍而且不会产生并发问题的操作,可以理解为读写锁是比互斥锁更乐观的锁,它保证读读可以并发,提高了并发编程的性能。
ReentrantReadWriteLock
Java的读写锁实现为ReentrantReadWriteLock,具体用法如下所示
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockExample {
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private int sharedResource = 0;
public int read() {
lock.readLock().lock();
try {
return sharedResource;
} finally {
lock.readLock().unlock();
}
}
public void write(int value) {
lock.writeLock().lock();
try {
sharedResource = value;
} finally {
lock.writeLock().unlock();
}
}
}