Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.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_Deadlock_Race Condition_Producer Consumer - Fatal编程技术网

我想使用Java中的生产者-消费者模型将竞争条件复制到死锁中

我想使用Java中的生产者-消费者模型将竞争条件复制到死锁中,java,multithreading,deadlock,race-condition,producer-consumer,Java,Multithreading,Deadlock,Race Condition,Producer Consumer,在wiki上,我找到了一个生产者-消费者程序的以下伪代码,该程序具有可能导致死锁的竞争条件: int itemCount = 0; procedure producer() { while (true) { item = produceItem(); if (itemCount == BUFFER_SIZE) { sleep(); } putItemIntoBuff

在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块中移动

  • 在调用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));
        }
    
    }
    
    private LinkedList sharedList=new LinkedList();
    私有int sharedValue=0;
    私有整数最大值限制=10;
    public void product()引发InterruptedException{
    随机=新随机();
    while(true){
    已同步(此){
    如果(sharedValue==MAX_LIMIT){/'product'线程在列表已满时等待
    等待();
    }
    sharedValue=sharedValue+1;
    sharedList.add(sharedValue);System.out.println(“增值:+sharedValue”);
    如果(sharedValue==1){
    notify();//如果列表不为空,则通知“消费”线程
    }
    }
    }
    }
    public void consume()引发InterruptedException{
    随机=新随机();
    while(true){
    已同步(此){
    如果(sharedValue==0){//'consume'在列表为空时等待
    等待();
    }
    sharedValue=sharedValue-1;
    sharedList.remove();System.out.println(“删除的值:+sharedValue”);
    if(sharedValue==最大限制-1){
    notify();//如果列表未满,则通知“product”
    }
    }
    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
                    }
                }
            }
    
        }
    
    private LinkedList sharedList=new LinkedList();
    私有volatile int sharedValue=0;
    私有整数最大值限制=10;
    public void product()引发InterruptedException{
    while(true){
    如果(sharedValue==MAX_LIMIT){/'product'线程在列表已满时等待
    已同步(此){
    等待();
    }
    }
    已同步(此){
    sharedValue=sharedValue+1;
    sharedList.add(sharedValue);
    System.out.println(“附加值:“+sharedValue”);
    }
    如果(sharedValue==1){
    已同步(此){
    notify();//如果列表不为空,则通知“消费”线程
    }
    }
    }
    }
    public void consume()引发InterruptedException{
    while(true){
    如果(sharedValue==0){//'consume'在列表为空时等待
    已同步(此){
    等待();
    }
    }
    已同步(此){
    sharedValue=sharedValue-1;
    sharedList.remove();
    System.out.println(“删除值:“+sharedValue”);
    }
    如果(sharedValue==最大值限制-1){
    已同步(此){
    notify();//如果列表未满,则通知“product”
    }
    }
    }
    }
    
    您的实现似乎与伪代码大不相同。伪代码不为one.FYI使用同步,这不是死锁的示例。死锁是指两个或多个线程在继续之前各自等待另一个线程释放一些锁。这是丢失通知的一个示例。死锁和丢失通知都是不同类型的活动性失败,它是一个或多个线程陷入等待某种永远不会发生的情况的通用名称。