我写了下面的测试代码在Java使用ReentantReadWriteLock来了解公平和不公平模式之间的区别。然而,我看到在两种模式下,结果和输出总是相同的。它似乎总是在公平模式下工作。谁能解释一下,在何种情况下,公平和不公平模式会导致不同的行为?
package lockTest;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MyLockTest {
static private ReadWriteLock myLock = new ReentrantReadWriteLock(false);
public class Reader extends Thread {
int val_;
public Reader(int val) {
val_ = val;
}
public void run() {
if (val_ > 0) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
myLock.readLock().lock();
System.out.println(Thread.currentThread().getName() + ": Reader inside critical section - val: " + val_ + "-----");
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myLock.readLock().unlock();
}
}
public class Writer extends Thread {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myLock.writeLock().lock();
System.out.println(Thread.currentThread().getName() + ": Writer inside critical section *****");
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myLock.writeLock().unlock();
}
}
public static void main(String[] args) {
MyLockTest test1 = new MyLockTest();
MyLockTest.Reader reader1 = test1.new Reader(0);
MyLockTest.Writer writer1 = test1.new Writer();
MyLockTest.Reader reader2 = test1.new Reader(1);
reader2.start();
writer1.start();
reader1.start();
}
}
输出总是:
Thread-0: Reader inside critical section - val: 0-----
Thread-1: Writer inside critical section *****
Thread-2: Reader inside critical section - val: 1-----
当我将锁创建更改为公平模式时,上面的输出是我期望看到的:
static private ReadWriteLock myLock = new ReentrantReadWriteLock(true);
对于非公平模式,我希望看到以下输出:
Thread-0: Reader inside critical section - val: 0-----
Thread-2: Reader inside critical section - val: 1-----
Thread-1: Writer inside critical section *****
使用“公平”与“非公平”模式会影响在争用情况下如何将锁分配给线程。
从Javadoc for ReentantReadWriteLock:使用非公平模式,未指定进入读写锁的顺序,而使用公平模式,线程使用近似到达顺序策略争夺条目。
我们可以看到使用公平/非公平是如何通过让一些线程争用同一个锁来影响程序执行的;请参阅下面的程序。
运行示例代码时,不同的线程会争用一个ReentrantWriteLock
;在1000次锁操作之后,我们转储每个线程获得锁的次数。
如果使用USE\u FAIR=false
,计数是随机的,可能的输出是:
Thread thread-B finished, count=920
Thread thread-A finished, count=79
Thread thread-D finished, count=0
Thread thread-C finished, count=0
在使用USE_FAIR=true
的情况下,输出总是像
Thread thread-D finished, count=249
Thread thread-A finished, count=250
Thread thread-C finished, count=250
Thread thread-B finished, count=250
示例代码
package sample1;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class UseLock {
public static void main(String[] args) {
UseLock o = new UseLock();
o.go();
}
private void go() {
TotalPermits tp = new TotalPermits();
tp.lock.writeLock().lock();
Contender a = new Contender(tp, "thread-A");
Contender b = new Contender(tp, "thread-B");
Contender c = new Contender(tp, "thread-C");
Contender d = new Contender(tp, "thread-D");
a.start();
b.start();
c.start();
d.start();
tp.lock.writeLock().unlock();
}
}
class TotalPermits {
private static final boolean USE_FAIR = true;
private int count = 1_000;
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(USE_FAIR);
public boolean get() {
try {
lock.writeLock().lock();
try {
Thread.sleep(1);
} catch (InterruptedException e) { }
return --count>0;
} finally {
lock.writeLock().unlock();
}
}
}
class Contender extends Thread {
private int count = 0;
final String name;
final TotalPermits tp;
Contender(TotalPermits tp, String name) {
this.tp = tp;
this.name = name;
}
@Override
public void run() {
while ( tp.get() ) {
count++;
}
System.out.printf("Thread %s finished, count=%d%n", name, count);
}
}
注:
上面的示例代码使用了一个“写”锁,一次只能由一个线程持有。所以我们可以用它来在竞争者之间划分N个许可证。另一方面,"读"锁可以由多个线程持有,只要没有一个线程持有写锁。
我一直在弄清楚口译员的确切工作方式,在谷歌上搜索了一下,得出了一些结论,只是希望有人能纠正一下,让我更好地了解口译员的工作。 所以我的理解是: 解释器是一种将代码从高级语言转换为机器格式的软件程序 现在我仍然不清楚中间发生的子过程,即。 解释器产生中间代码 然后优化解释的代码 然后生成目标代码 并最终执行 还有一些问题: 那么解释器是否单独负责生成目标代码?并执行它? 执行是否意味着它在JVM或底
问题内容: 我无法确切地理解反射模式如何处理我的数组。我 有一个非常简单的数组: [[ 1. 1. 1. 1. 1.] [ 2. 2. 2. 2. 2.] [ 4. 4. 4. 4. 4.] [ 5. 5. 5. 5. 5.]] Applying a uniform (mean) filter with a window size of 3 I get the following: [[ 1.33
问题内容: 我在jquery图像滑块演示中找到了reset.css文件,但它从未包含在主index.html文件中。应该做什么,更重要的是,您将它放在哪里?你把它之前 任何引用的样式表()? 这是reset.css内部的代码 问题答案: 最初,关于样式的工作方式还没有标准化,每个浏览器都实现了自己认为正确的方式。您在IE中看到太多有关样式错误的问题的原因之一是,因为IE是样式方面与其他浏览器最不相
API文档说明: 这个类的构造函数接受一个可选的公平性参数。当设置为true时,在争用状态下,锁倾向于授予对等待时间最长的线程的访问权限。 注意,锁的公平性并不能保证线程调度的公平性。因此,使用公平锁的许多线程中的一个可以连续多次获得它,而其他活动线程没有进展,并且当前没有持有锁。 我无法理解第2点: 如果一个线程连续多次获得锁,那么根据第1点,其他线程将等待更长时间,这确实意味着它们下次将获得锁
因此,Dart API对==运算符这样说: 相等运算符。 所有对象的默认行为是,当且仅当此对象和其他对象是同一对象时,才返回true。 重写此方法以在类上指定不同的相等关系。重写方法仍然必须是等价关系。也就是说,它必须是: Total:它必须为所有参数返回一个布尔值。它不应该扔。 反身:对于所有对象 必须为。 对称:对于所有对象< code>o1和< code > O2 ,< code > O1
我正在研究Sping XML配置,我对构造函数注入配置有以下疑问。 我举了以下例子: 好的。我很清楚会发生什么:首先,帐户存储库bean被创建为一个com.acme.的帐户存储库实例,而客户存储库bean被创建为一个com.acme.的客户存储库实例 然后创建transferService bean作为com的一个istance。顶峰TransferServiceImpl类和前2个bean在bea