带有信号量的java ProducerConsumer陷入死锁
我正在尝试创建仅使用信号量的生产者-消费者。使用以下代码
public class Application {
public static int id = 0;
public static void main(String[] args) {
Semaphore producerSem = new Semaphore(1);
Semaphore consumerSem = new Semaphore(1);
Queue<Integer> line = new LinkedList<>();
Runnable produce = () -> {
try {
producerSem.acquire();
System.out.println(Thread.currentThread().getName() + " producing");
while (line.size() > 10) continue;
Thread.sleep(2000);
line.offer(id);
System.out.println(Thread.currentThread().getName() + " produced thing with id: " + id);
id++;
System.out.println(Thread.currentThread().getName() + " finished producing");
producerSem.release();
}
catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable consume = () -> {
try {
consumerSem.acquire();
System.out.println(Thread.currentThread().getName() + " consuming");
while (line.size() < 1) continue;
int product = line.remove();
System.out.println(Thread.currentThread().getName() + " consumed thing with id: " + product);
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + " finished consuming");
consumerSem.release();
}
catch (InterruptedException e) {
e.printStackTrace();
}
};
for (int i = 0; i < 100; i++) {
new Thread(consume, "Consumer - " + i).start();
new Thread(produce, "Producer - " + i).start();
}
}
}
它陷入了死锁,我无法调试它,因为它进入id 10并停止,所以看起来有一个元素被删除了,但它无法向前移动。在任何地方使用断点都可以正常工作,即使在任何任务结束时也是如此
# 1 楼答案
我认为这是一个很好的练习,只使用信号量来编写线程安全的代码
你应该保护三个方面:
id
是一个简单的全局整数,一次只能写入一个进程李>修改后的代码可能是:
有输出