Java 生产者/消费者使用信号量;陷入僵局
根据这一点,我想用信号量来模拟p/C问题。我陷入了僵局,我不知道是什么问题Java 生产者/消费者使用信号量;陷入僵局,java,multithreading,mutex,semaphore,Java,Multithreading,Mutex,Semaphore,根据这一点,我想用信号量来模拟p/C问题。我陷入了僵局,我不知道是什么问题 public static void main(String[] args) { CustomBlockingQueue blockingQueue = new CustomBlockingQueue(); new Thread(new Producer(blockingQueue)).start(); new Thread(new Consumer(blockingQue
public static void main(String[] args) {
CustomBlockingQueue blockingQueue = new CustomBlockingQueue();
new Thread(new Producer(blockingQueue)).start();
new Thread(new Consumer(blockingQueue)).start();
}
}
@SuppressWarnings("serial")
class CustomBlockingQueue extends LinkedList<Object> {
private static final int MAX_SIZE = 10;
private Semaphore mutex = new Semaphore(1);
private Semaphore fillCount = new Semaphore(0);
private Semaphore emptyCount = new Semaphore(MAX_SIZE);
@Override
public boolean offer(Object e) {
try {
mutex.acquire();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
boolean result = super.offer(e);
System.out.println("offer " + size());
try {
fillCount.release();
emptyCount.acquire();
mutex.release();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return result;
}
@Override
public Object poll() {
try {
mutex.acquire();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
Object result = super.poll();
System.out.println("poll " + size());
try {
emptyCount.release();
fillCount.acquire();
mutex.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
}
class Producer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Producer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(2));
blockingQueue.offer(new Object());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Consumer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(4));
blockingQueue.poll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
publicstaticvoidmain(字符串[]args){
CustomBlockingQueue blockingQueue=新建CustomBlockingQueue();
新线程(新生产者(blockingQueue)).start();
新线程(新使用者(blockingQueue)).start();
}
}
@抑制警告(“串行”)
类CustomBlockingQueue扩展LinkedList{
专用静态最终整数最大值=10;
专用信号量互斥=新信号量(1);
私有信号量fillCount=新信号量(0);
私有信号量emptyCount=新信号量(最大大小);
@凌驾
公共布尔报价(对象e){
试一试{
mutex.acquire();
}捕捉(中断异常e2){
e2.printStackTrace();
}
布尔结果=super.offer(e);
System.out.println(“offer”+size());
试一试{
fillCount.release();
emptyCount.acquire();
mutex.release();
}捕捉(中断异常e1){
e1.printStackTrace();
}
返回结果;
}
@凌驾
公共对象轮询(){
试一试{
mutex.acquire();
}捕捉(中断异常e2){
e2.printStackTrace();
}
对象结果=super.poll();
System.out.println(“poll”+size());
试一试{
emptyCount.release();
fillCount.acquire();
mutex.release();
}捕捉(中断异常e){
e、 printStackTrace();
}
返回结果;
}
}
类生成器实现了Runnable{
私有定制阻塞队列阻塞队列;
私有随机=新随机();
公共生产者(CustomBlockingQueue blockingQueue){
this.blockingQueue=blockingQueue;
}
@凌驾
公开募捐{
而(!Thread.currentThread().isInterrupted()){
试一试{
时间单位。秒。睡眠(随机。nextInt(2));
blockingQueue.offer(新对象());
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}
类使用者实现Runnable{
私有定制阻塞队列阻塞队列;
私有随机=新随机();
公共消费者(CustomBlockingQueue blockingQueue){
this.blockingQueue=blockingQueue;
}
@凌驾
公开募捐{
而(!Thread.currentThread().isInterrupted()){
试一试{
时间单位。秒。睡眠(随机。nextInt(4));
blockingQueue.poll();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
使用信号量
信号量解决了唤醒调用丢失的问题。在下面的解决方案中,我们使用两个信号量fillCount和emptyCount来解决这个问题。fillCount是缓冲区中要读取的项目数,emptyCount是缓冲区中可以写入项目的可用空间数。fillCount递增,emptyCount递减当一个新的项目被放入缓冲区中时,如果生产者试图减去EvyTyCalt,而它的值为0,则生产者被置于睡眠状态。下一次使用一个项目时,EpTyCube递增,生产者就会醒来。消费者类似地工作。 < P>您可以考虑使用一个代替互斥锁的情况。等着你 另一方面,我有一个演示生产者/消费者竞争条件的旧页面(与伪中断相反)。但我的实现不使用信号量,因此我不确定它是否能帮助您:
你可以考虑使用一个代替互斥锁并等待的例子。 另一方面,我有一个演示生产者/消费者竞争条件的旧页面(与伪中断相反)。但我的实现不使用信号量,因此我不确定它是否能帮助您:
您的锁定顺序错误: 需要提供:
emptyCount.acquire();
mutex.acquire();
doModification();
mutex.release();
fillCount.release();
投票需要进行类似的更改:
fillCount.acquire();
mutex.acquire();
doModification();
mutex.release();
emptyCount.release();
在您的实现中,您在等待信号量的同时持有互斥锁,这会导致问题,因为另一个线程可能正在等待互斥锁以释放信号量。您的锁定顺序错误: 需要提供:
emptyCount.acquire();
mutex.acquire();
doModification();
mutex.release();
fillCount.release();
投票需要进行类似的更改:
fillCount.acquire();
mutex.acquire();
doModification();
mutex.release();
emptyCount.release();
在您的实现中,您在等待信号量的同时持有互斥锁,这会导致问题,因为另一个线程可以等待互斥锁以释放信号量。省去您自己的麻烦:使用线程安全队列。同意-这些都是在库中为您实现的-无需费劲地去做!我想要自己为了使用semaphoreBTW@ASD解决这个问题,我建议在
finally{}中执行.release()
调用
block.save yourself Thaneors:使用线程安全队列。同意-这些都是在库中为您实现的-无需费劲!我希望自己能够使用故意使用信号量ebtw@ASD来解决这个问题,我建议您在finally{}中执行.release()
调用
block。我知道BlockingQueue,但我想自己用故意的信号量来解决这个问题。我想@ASD。我想我会指出这一点。我还放了一个链接到我的生产者/消费者页面供参考。谢谢你的回复,但我已经用这种方式解决了这个问题(但与你有点不同)。我知道BlockingQueue,但我想自己用故意的信号量来解决这个问题。我想@ASD。我想我会指出这一点。我还放了一个链接到我的生产者/消费者页面供参考。谢谢你的回复,但我已经用这种方式解决了这个问题(但与你有点不同)。+1你必须努力获得这个或更多信息