Java 可重入写回。读写获取优先级
我研究可重入式写锁 java文档中的代码片段: 在最早的一次读取之后,线程才会获取读取锁 当前等待写入线程已获取并释放写入 锁 正如我所理解的那样 读取持续时间-1时间单位 写入持续时间-3时间单位Java 可重入写回。读写获取优先级,java,multithreading,concurrency,locking,reentrantreadwritelock,Java,Multithreading,Concurrency,Locking,Reentrantreadwritelock,我研究可重入式写锁 java文档中的代码片段: 在最早的一次读取之后,线程才会获取读取锁 当前等待写入线程已获取并释放写入 锁 正如我所理解的那样 读取持续时间-1时间单位 写入持续时间-3时间单位 时间0-已获取写入锁 时间1-读取锁定尝试读取 时间2- 写锁试写 因此,我期望以下顺序: 首笔 第二次写入 阅读 我的实验代码: public class RWLockCalculator { static long initTime = System.currentTimeMillis(
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));
}
}
输出:
因此我得到
是否可能中断FIFO顺序 更新 请比较java文档中的两个兄弟片段(关于公平模式): 首先 尝试获取公平读取锁(非可重入)的线程将在写入锁被持有或存在等待写入线程时阻塞。在当前等待的最旧写入线程获取并释放写锁之前,该线程不会获取读锁。当然,如果等待的写入程序放弃等待,将一个或多个读卡器线程作为队列中最长的等待程序保留写锁,则这些读卡器将被分配读锁。 第二: 尝试获取公平写锁(非可重入)的线程将阻塞,除非读锁和写锁都是空闲的(这意味着没有等待的线程)。(请注意,非阻塞的ReentrantReadWriteLock.ReadLock.tryLock()和ReentrantReadWriteLock.WriteLock.tryLock()方法不支持此公平设置,并且将在可能的情况下获取锁,而不考虑等待的线程。) 我不完全理解其中所写内容的含义,但我看到,
ReentrantReadWriteLock
使用不同的策略获取读锁和写锁。我建议,如果政治在Javadoc中是一样的,就不会写两个缩进
ReadLock可以共享锁。这仅仅是一个区别吗?首先,应在公平模式下创建可重入的写锁,以强制特定的锁获取顺序:
private static ReadWriteLock lock = new ReentrantReadWriteLock(true);
然后,非常清楚地描述了您的案例:
当构造为公平时,线程使用近似到达顺序策略争夺条目。释放当前持有的锁时,将为等待时间最长的单个写入线程分配写锁,或者如果有一组读线程比所有等待的写入线程等待时间更长,则将为该组分配读锁
由于您的读卡器线程等待的时间比第二个写卡器线程长,因此它在写卡器线程之前获得一个锁。我认为“当前等待的最早的写卡器线程”是读卡器线程请求锁时的线程。因此,在你的例子中,没有等待的作者,读者是下一个。@SpaceTrucker,这公平吗?FIFO?是否可能中断FIFO顺序?所有线程都位于公共队列中。无论是写锁还是读锁,它都希望获得?Яаааааааааааааа。Получается, что всё равно какой лок(на чтение или на запись) ждёт поток - все они стоят в очереди. 读取和写入锁定策略必须不同,因为写入锁定是独占的,而读取锁定不是独占的。据我所知,它本质上充当写入线程和读线程组(可能共享锁)的FIFO队列。
private static ReadWriteLock lock = new ReentrantReadWriteLock(true);