- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 wiki 上,我发现了以下生产者-消费者程序的伪代码,该程序具有可能导致死锁的竞争条件:
int itemCount = 0;
procedure producer()
{
while (true)
{
item = produceItem();
if (itemCount == BUFFER_SIZE)
{
sleep();
}
putItemIntoBuffer(item);
itemCount = itemCount + 1;
if (itemCount == 1)
{
wakeup(consumer);
}
}
}
procedure consumer()
{
while (true)
{
if (itemCount == 0)
{
sleep();
}
item = removeItemFromBuffer();
itemCount = itemCount - 1;
if (itemCount == BUFFER_SIZE - 1)
{
wakeup(producer);
}
consumeItem(item);
}
}
通过此实现,应该发生以下情况:
消费者刚刚读取了变量 itemCount,注意到它为零,并且即将移入 if block 内。
就在调用 sleep 之前,消费者被中断并恢复生产者。
生产者创建一个项目,将其放入缓冲区,并增加 itemCount。
由于缓冲区在最后一次添加之前为空,因此生产者尝试唤醒消费者。
不幸的是,消费者尚未休眠,唤醒调用丢失。当消费者恢复时,它会进入休眠状态,并且永远不会再次被唤醒。这是因为只有当 itemCount 等于 1 时,消费者才会被生产者唤醒。
生产者将循环直到缓冲区已满,之后它也会进入休眠状态。
我希望能够在 Java 中复制这一点,但到目前为止,在运行我的程序多次后我无法做到这一点。这是我的代码:
private LinkedList<Integer> sharedList = new LinkedList<Integer>();
private int sharedValue = 0;
private int MAX_LIMIT = 10;
public void produce() throws InterruptedException {
Random random = new Random();
while (true) {
synchronized (this) {
if (sharedValue == MAX_LIMIT) { //'produce' thread waits if list is full
wait();
}
sharedValue = sharedValue + 1;
sharedList.add(sharedValue); System.out.println("added value: " + sharedValue);
if (sharedValue == 1) {
notify(); //notifies 'consume' thread if list is not empty
}
}
}
}
public void consume() throws InterruptedException {
Random random = new Random();
while (true) {
synchronized (this) {
if (sharedValue == 0) { //'consume' waits if list is empty
wait();
}
sharedValue = sharedValue - 1;
sharedList.remove(); System.out.println("removed value: " + sharedValue);
if (sharedValue == MAX_LIMIT-1) {
notify(); //notifies 'produce' if list is not full
}
}
Thread.sleep(random.nextInt(1000));
}
}
最佳答案
原因是您同步了整个迭代步骤。 synchronized (this) {...}
下的两个代码块将按顺序运行。
您可以通过以下方式复制它:
private LinkedList<Integer> sharedList = new LinkedList<Integer>();
private volatile int sharedValue = 0;
private int MAX_LIMIT = 10;
public void produce() throws InterruptedException {
while (true) {
if (sharedValue == MAX_LIMIT) { //'produce' thread waits if list is full
synchronized (this) {
wait();
}
}
synchronized (this) {
sharedValue = sharedValue + 1;
sharedList.add(sharedValue);
System.out.println("added value: " + sharedValue);
}
if (sharedValue == 1) {
synchronized (this) {
notify(); //notifies 'consume' thread if list is not empty
}
}
}
}
public void consume() throws InterruptedException {
while (true) {
if (sharedValue == 0) { //'consume' waits if list is empty
synchronized (this) {
wait();
}
}
synchronized (this) {
sharedValue = sharedValue - 1;
sharedList.remove();
System.out.println("removed value: " + sharedValue);
}
if (sharedValue == MAX_LIMIT - 1) {
synchronized (this) {
notify(); //notifies 'produce' if list is not full
}
}
}
}
关于java - 我想使用 Java 中的生产者-消费者模型将竞争条件复制到死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49634542/
我有类似下面的代码: ... id: myComponent signal updateState() property variant modelList: [] Repeater { mo
我正在处理一些我无法展示的私有(private)代码,但我已经制作了一些示例代码来描述我的问题: 主.c: #include #include #include #include typede
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: what are the differences in die() and exit() in PHP? 我想
在编写 Perl 模块时,在模块内部使用 croak/die 是一个好习惯吗? 毕竟,如果调用者不使用 eval block ,模块可能会使调用它的程序崩溃。 在这些情况下,最佳做法是什么? 最佳答案
我有一些搜索线程正在存储结果。我知道当线程启动时,JVM native 代码会代理在操作系统上创建新 native 线程的请求。这需要 JVM 之外的一些内存。当线程终止并且我保留对它的引用并将其用作
我刚刚花了很多时间调试一个我追溯到 wantarray() 的问题。 .我已将其提炼为这个测试用例。 (忽略 $! 在这种情况下不会有任何有用信息的事实)。我想知道为什么wantarray在第二个示例
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
我正在尝试将此表格用于: 如果任何 $_POST 变量等于任何其他 $_POST 变量抛出错误。 如果只有几个,那不是问题,但我有大约 20 个左右所以如果我想这样做,我将不得不像这样 但这
每次我运行: hadoop dfsadmin -report 我得到以下输出: Configured Capacity: 0 (0 KB) Present Capacity: 0 (0 KB) DFS
我是一名优秀的程序员,十分优秀!