前面我们已经学习了很多关于多线程的知识,现在我们来学习jdk提交的锁--可重入读写锁,可重入读写锁就是指当一个线程持有某个对象的锁,其他线程也可以获取和进入同步区域。特别在读写的时候,如果A线程在获取锁,并且正在读,如果读线程B也要进行读,如果AB的锁是互斥锁就会不是很高效,正常情况:读写锁互斥,写写锁互斥,多个读读锁不用互斥。
下面看一下我们用ReentrantReadWriteLock实现:
package javaThread;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReentrantReadWriteLockThread {
public static void main(String[] args) {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final ReentrantReadWriteLockData data = new ReentrantReadWriteLockData(lock);
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
data.ReadNum();
}
}
}.start();
}
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
data.WriteNum();
}
}
}.start();
}
}
static class ReentrantReadWriteLockData {
private ReentrantReadWriteLock mLock;
public ReentrantReadWriteLockData(ReentrantReadWriteLock lock) {
mLock = lock;
}
public void ReadNum() {
mLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " ReadNum sleep ");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " ReadNum sleep end");
} catch (InterruptedException e) {
} finally {
mLock.readLock().unlock();
}
}
public void WriteNum() {
mLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " WriteNum sleep ");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " WriteNum sleep end");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mLock.writeLock().unlock();
}
}
}
}
Thread-2 ReadNum sleep
Thread-1 ReadNum sleep
Thread-1 ReadNum sleep end
Thread-2 ReadNum sleep end
<span style="color:#ff0000;">Thread-3 WriteNum sleep
Thread-3 WriteNum sleep end
Thread-4 WriteNum sleep
Thread-4 WriteNum sleep end</span>
<span style="color:#33ff33;">Thread-0 ReadNum sleep
Thread-1 ReadNum sleep
Thread-2 ReadNum sleep </span>
Thread-0 ReadNum sleep end
Thread-2 ReadNum sleep end
Thread-1 ReadNum sleep end
Thread-0 ReadNum sleep
Thread-2 ReadNum sleep
Thread-1 ReadNum sleep
红色部分证明只有一个线程在写,绿色部分表示有三个线程同时在读。