Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 生产者/消费者使用信号量;陷入僵局_Java_Multithreading_Mutex_Semaphore - Fatal编程技术网

Java 生产者/消费者使用信号量;陷入僵局

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

根据这一点,我想用信号量来模拟p/C问题。我陷入了僵局,我不知道是什么问题

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你必须努力获得这个或更多信息