使用信号量的监控程序在java中无法正常工作
我试图用java创建一个多生产者多消费者问题的解决方案(即监视器) 我决定使用Semaphore类并按如下方式进行同步使用信号量的监控程序在java中无法正常工作,java,multithreading,semaphore,synchronized,producer-consumer,Java,Multithreading,Semaphore,Synchronized,Producer Consumer,我试图用java创建一个多生产者多消费者问题的解决方案(即监视器) 我决定使用Semaphore类并按如下方式进行同步 import java.util.concurrent.Semaphore; public class PC implements Runnable { Semaphore s; Object lock; boolean isProducer; final int ProcessCount = 4; final int producer
import java.util.concurrent.Semaphore;
public class PC implements Runnable {
Semaphore s;
Object lock;
boolean isProducer;
final int ProcessCount = 4;
final int producerDelay = 1500;
final int consumerDelay = 1000;
public static void main(String[] args) {
new PC();
}
PC() {
this.s = new Semaphore(10);
this.lock = new Object();
this.isProducer = true;
// create few consumers and producers
for (int i = 0; i < ProcessCount; i++) {
new Thread(this).start();
}
}
public void run() { //alternately create producers and consumers
if (isProducer) {
isProducer = false;
producer();
} else {
isProducer = true;
consumer();
}
}
void producer() {
try {
while (true) {
synchronized (this.lock) {
s.release(); // produce an resource
}
System.out.println("produced:\tAvailable now:\t" + s.availablePermits());
Thread.sleep(producerDelay);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
void consumer() {
try {
while (true) {
synchronized (this.lock) {
s.acquire(); // consume resource
}
System.out.println("consumed:\tAvailable now:\t" + s.availablePermits());
Thread.sleep(consumerDelay);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
当生产者延迟较低时:
程序中出了什么问题?首先,创建一个带有10个初始许可证的信号量,如前所述。它不是上限,因此
release()
可以使可用许可证的数量超过10个
另外,请查看下面的代码:
synchronized (this.lock) {
s.acquire(); // consume resource
}
你得到了锁。如果没有可用的资源,线程将暂停,但不会释放锁。因此,下面的代码无法获取锁并且无法执行。使用者等待许可证,生产者等待锁,导致死锁
synchronized (this.lock) {
s.release(); // produce an resource
}
您可以通过不同步
s.acquire()
和s.release()
来解决此问题。首先,创建一个具有10个初始许可证的信号量,如前所述。它不是上限,因此release()
可以使可用许可证的数量超过10个
另外,请查看下面的代码:
synchronized (this.lock) {
s.acquire(); // consume resource
}
你得到了锁。如果没有可用的资源,线程将暂停,但不会释放锁。因此,下面的代码无法获取锁并且无法执行。使用者等待许可证,生产者等待锁,导致死锁
synchronized (this.lock) {
s.release(); // produce an resource
}
您可以通过不同步
s.acquire()
和s.release()
来解决此问题,这就是将要发生的情况
void producer() {
try {
while (true) {
//***All producers are stuck here because "first consumer" is having the lock.
synchronized (this.lock) {
s.release(); // produce an resource
}
System.out.println("produced:\tAvailable now:\t" + s.availablePermits());
Thread.sleep(producerDelay);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
void consumer() {
try {
while (true) {
//***All other consumers are stuck here because of line below.
synchronized (this.lock) {
//***"First consumer" is stuck here waiting s.release()
s.acquire(); // consume resource
}
System.out.println("consumed:\tAvailable now:\t" + s.availablePermits());
Thread.sleep(consumerDelay);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
这就是将要发生的事情
void producer() {
try {
while (true) {
//***All producers are stuck here because "first consumer" is having the lock.
synchronized (this.lock) {
s.release(); // produce an resource
}
System.out.println("produced:\tAvailable now:\t" + s.availablePermits());
Thread.sleep(producerDelay);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
void consumer() {
try {
while (true) {
//***All other consumers are stuck here because of line below.
synchronized (this.lock) {
//***"First consumer" is stuck here waiting s.release()
s.acquire(); // consume resource
}
System.out.println("consumed:\tAvailable now:\t" + s.availablePermits());
Thread.sleep(consumerDelay);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
我不明白为什么你需要
同步的
块来调用你的信号量
,你能澄清一下吗?@NicolasFilotto我认为信号量不是线程安全的(我猜监视器是线程安全的,而信号量不是线程安全的),这就是我使用锁的原因。我错了吗?是的,你错了,这是我们可以用来创建线程安全类的可用内置工具之一。我不明白为什么需要同步的块来调用你的信号量,你能澄清一下吗?@NicolasFilotto我认为信号量不是线程安全的(我猜监视器是线程安全的,而信号量不是线程安全的),这就是我使用锁的原因。我错了吗?是的,你错了,它是一个可用的内置工具,我们可以使用它创建线程安全的类,信号量线程安全吗?我认为信号量不是线程安全的,而监视器是线程安全的。是的,信号量是线程安全的,不需要同步它们的调用。检查这个:信号量是吗线程安全?我认为信号量不是线程安全的,而监视器是线程安全的。是的,信号量是线程安全的,不需要同步它们的调用。检查此项: