读写锁ReentrantReadWriteLock的疑问(转载)
来源:互联网 发布:软件开发书籍推荐 编辑:程序博客网 时间:2024/06/06 00:45
Jdk5中的concurrent包中有一个ReadWriteLock接口以及它的实现(ReentrantReadWriteLock)。通过这个名字,以及它提供的两个方法:
- readLock()
- writeLock()
可以猜测,它提供了两个锁,一个用来写入,一个用来读取。因为读取不改变数据,可假设读取锁可同时被多个线程持有;而写入锁只能被一个线程持有,因为写入将改变数据。
由于该类的文档写得异常难懂,所以这里用代码来测试。
一、读取锁可同时被多个线程持有
public class ReadLockCanBeHoldByMultiThreadTest {
public static void main(String[] args) {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final ReadLock readLock = lock.readLock();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
readLock.lock();
System.out.println(Thread.currentThread().getName() + " holds the read lock");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " exits");
};
}.start();
}
}
}
输出结果如下:
Thread-0 holds the read lock
Thread-2 holds the read lock
Thread-1 holds the read lock
Thread-0 exits
Thread-1 exits
Thread-2 exits
可见读取锁的确可同时被多个线程持有。
二、写入锁不可同时被多个线程持有
public class WriteLockCannotBeHeldByMultiThreads {
public static void main(String[] args) {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final WriteLock writeLock = lock.writeLock();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
writeLock.lock();
System.out.println(Thread.currentThread().getName() + " holds the read lock");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
writeLock.unlock();
System.out.println(Thread.currentThread().getName() + " exits");
};
}.start();
}
}}
结果如下:
Thread-0 holds the read lock
Thread-0 exits
Thread-1 holds the read lock
Thread-1 exits
Thread-2 holds the read lock
Thread-2 exits
可见写入锁必须在释放后,才能被另一个线程拿到。
三、写入锁与读取锁不可同时被不同线程持有
public class ReadWriteLockCannotBeHeldAtTheSameTime {
public static void main(String[] args) throws Exception {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final ReadLock readLock = lock.readLock();
final WriteLock writeLock = lock.writeLock();new Thread() {
public void run() {
readLock.lock();
System.out.println(Thread.currentThread().getName() + " holds the read lock");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
readLock.unlock();
System.out.println(Thread.currentThread().getName() + " released the read lock");
};
}.start();// let the first thread have enough time to hold the read lock
Thread.sleep(1000);new Thread() {
public void run() {
writeLock.lock();
System.out.println(Thread.currentThread().getName() + " holds the write lock");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
writeLock.unlock();
System.out.println(Thread.currentThread().getName() + " released the write lock");
};
}.start();}
}
结果如下:
Thread-0 holds the read lock
Thread-0 released the read lock
Thread-1 holds the write lock
Thread-1 released the write lock
可见读取写被一线程持有后,其它线程必须等它释放后,才能拿到写入锁。反过来也一样,如果写入锁被拿了,读取锁也就拿不到了。
四、某线程拿到写入锁后,还能再拿读取锁
public class AThreadCanHoldWriteAndReadLock {
public static void main(String[] args) {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final ReadLock readLock = lock.readLock();
final WriteLock writeLock = lock.writeLock();
writeLock.lock();
System.out.println("Hold the write lock");
readLock.lock();
System.out.println("Hold the read lock");
}
}
输出:
Hold the write lock
Hold the read lock
五、反过来不行,拿到读取锁后,就拿不到写入锁了
public class AThreadCannotHoldReadAndWriteLock {
public static void main(String[] args) {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
final ReadLock readLock = lock.readLock();
final WriteLock writeLock = lock.writeLock();
readLock.lock();
System.out.println("Hold the read lock");
writeLock.lock();
System.out.println("Hold the write lock");
}
}
输出如下:
Hold the read lock
程序永远卡在这里了,因为拿不到写入锁而陷入等待。
(待续)
转载地址 http://freewind.me/blog/20111031/543.html
感谢原作者
- 读写锁ReentrantReadWriteLock的疑问(转载)
- 【转载】ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- ReentrantReadWriteLock读写锁的使用
- 将PDF文档整理为WORD文档
- Codeforces#135(div.2) E.Parking lot【线段树】
- CDC的文字处理程序的编写
- ReentrantReadWriteLock(转载)
- Nebula level00
- 读写锁ReentrantReadWriteLock的疑问(转载)
- 白话数字签名
- oracle---表操作
- IOS中显示和隐藏状态栏的网络活动标志
- HDU 2845 最大非连续子段和 二维dp
- 内存管理(一)
- 使用指针来传递对象的例子对比
- Java 使用dom读取XML文件及对中文字符的支持
- 安装MYSLQ数据库异常cannot create windows service for mysql.error:0