我研究ReentrantReadWriteLock
来自java文档的代码片段:
在当前最老的等待写入线程获得并释放写锁之前,线程将不会获取读锁。
正如我所理解的那样。
读取时间-1时间单位
写入持续时间-3时间单元
因此,我期望以下顺序:
我的实验代码:
public class RWLockCalculator {
static long initTime = System.currentTimeMillis();
private static int calculatedValue = 0;
private static ReadWriteLock lock = new ReentrantReadWriteLock();
public void calculate(int value) {
lock.writeLock().lock();
try {
System.out.println("write lock acquired at "+ (System.currentTimeMillis()-RWLockCalculator.initTime));
this.calculatedValue = 1;
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.writeLock().unlock();
}
}
public int getCalculatedValue() {
lock.readLock().lock();
try {
System.out.println("read lock acquired at "+ (System.currentTimeMillis()-RWLockCalculator.initTime));
Thread.sleep(100);
return calculatedValue;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return -1;
} finally {
lock.readLock().unlock();
}
}
}
class Test {
public static void main(String[] args) throws InterruptedException {
new WriteThread().start();
Thread.sleep(100);
new ReadThread().start();
Thread.sleep(100);
new WriteThread().start();
}
}
class ReadThread extends Thread {
@Override
public void run() {
System.out.println(new RWLockCalculator().getCalculatedValue() + ", " + (System.currentTimeMillis() - RWLockCalculator.initTime));
}
}
class WriteThread extends Thread {
@Override
public void run() {
new RWLockCalculator().calculate(99);
System.out.println("I have written in " + (System.currentTimeMillis() - RWLockCalculator.initTime));
}
}退出:
write lock acquired at 0
I have written in 300
read lock acquired at 300
1, 400
write lock acquired at 400
I have written in 700所以我得到了
我为什么要得到这个结果?
有可能打破FIFO的顺序吗?
更新
请比较来自java的两个兄弟级代码段(关于公平模式):
第一
一个试图获得公平读锁(非真实地)的线程,如果持有写锁,或者存在等待写入线程,则会阻塞。在当前最老的等待写入线程获得并释放写入锁之前,线程将不会获取读锁。当然,如果等待的写入器放弃等待,留下一个或多个读取器线程作为队列中最长的等待者,并且没有写入锁,那么这些读取器将被分配读锁。
第二:
一个线程试图获得一个公平的写锁(非真实地)将阻塞,除非读锁和写锁都是空闲的(这意味着没有等待的线程)。(请注意,非阻塞的ReentrantReadWriteLock.ReadLock.tryLock()和ReentrantReadWriteLock.WriteLock.tryLock()方法不符合此公平设置,如果可能的话将获取锁,无论等待线程如何。)
我不完全理解在那里写什么的意思,但是我看到ReentrantReadWriteLock使用不同的策略来获得读锁和写锁。我建议,如果在java中政治是一样的,doc不会写两个缩进。
ReadLock可以共享锁。只有一个不同吗?
发布于 2014-04-16 09:34:16
首先,应该以公平的方式创建ReentrantReadWriteLock,以强制执行特定的锁获取顺序:
private static ReadWriteLock lock = new ReentrantReadWriteLock(true);然后,javadoc非常清楚地描述了您的情况:
当以公平的方式构造时,线程会使用一个近似到达顺序的策略来争夺条目.当当前持有的锁释放时,将为等待时间最长的单个写入线程分配写锁,或者如果有一组读取器线程等待时间超过所有等待的写入线程,则该组将被分配读锁。
由于您的读者线程等待的时间比第二个写入线程长,因此它在写入线程之前获得一个锁。
https://stackoverflow.com/questions/23104012
复制相似问题