Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.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_Monitoring_Deadlock_Reentrantlock - Fatal编程技术网

Java 为锁定指定多个条件时会发生死锁

Java 为锁定指定多个条件时会发生死锁,java,multithreading,monitoring,deadlock,reentrantlock,Java,Multithreading,Monitoring,Deadlock,Reentrantlock,我的程序需要从10向后打印到1。每个数字打印自 一根线。它对多个条件对象使用一个锁。但是 程序运行时会导致死锁。这是我的节目 这个班学习很好 import java.util.concurrent.*; import java.util.*; public class Backward { public static void main(String[] args) { BackwardThread[] threads = new BackwardThread[10];

我的程序需要从10向后打印到1。每个数字打印自 一根线。它对多个条件对象使用一个锁。但是 程序运行时会导致死锁。这是我的节目


这个班学习很好

import java.util.concurrent.*;
import java.util.*;

public class Backward {
   public static void main(String[] args) {
      BackwardThread[] threads = new BackwardThread[10];
      MonitorArray monitorArray = new MonitorArray(10);
      for(int i = 0; i < 10; ++i) {
         threads[i] = new BackwardThread("thread" + i, i, monitorArray);
         threads[i].start();
      }
   }
}
import java.util.concurrent.*;
import java.util.*;

public class BackwardThread extends Thread {
   private int id;
   private MonitorArray monitorArray;

   public BackwardThread(String name, int id, MonitorArray monitorArray) {
       super(name);
       this.id = id;
       this.monitorArray = monitorArray;
   }

  public void run() {
      monitorArray.waitTurn(id);
      System.out.println("hello world thread id = " + id);
      monitorArray.signalDone(id);
  }
}

似乎所有线程都永远处于锁定状态,条件[id].signal()不起作用

import java.util.concurrent.locks.*;
import java.util.concurrent.locks.Condition;

public class MonitorArray {

    private Lock lockvar;
    private Condition[] conditions;
    private int turn;

    public MonitorArray(int num) {
        this.lockvar = new ReentrantLock();
        this.conditions = new Condition[num];
        turn = num;
        for (int i = 0; i < num; ++i) {
            conditions[i] = lockvar.newCondition();
        }
        // TODO: need to initialize new variable here
    }
    public void waitTurn(int id) {
        lockvar.lock();
        while (id != turn) {
            try {
                conditions[id].await();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
        lockvar.unlock();
    }

    public void signalDone(int id) {
        lockvar.lock();
        // TODO: Need to modify new variable here to allow one of the threads
        // blocked on the while to continue
        turn--;
        if (id != 0) {
            conditions[id].signal();
        }

        lockvar.unlock();
    }
}
import java.util.concurrent.locks.*;
导入java.util.concurrent.locks.Condition;
公共类监视器数组{
私钥锁;
私人条件[]条件;
私人内翻;
公共监视器阵列(int num){
this.lockvar=new ReentrantLock();
this.conditions=新条件[num];
圈数=num;
对于(int i=0;i
我已经找到了解决方案,我将在我的代码注释中给出我的解释

import java.util.concurrent.locks.*;
import java.util.concurrent.locks.Condition;

public class MonitorArray {

    private Lock lockvar;
    private Condition[] conditions;
    private int turn;

    public MonitorArray(int num) {
        this.lockvar = new ReentrantLock();
        this.conditions = new Condition[num];

        /*
        / the turn value should should be num-1(9) instead of num(10) 
        / because if turn = 10 so all threads will be in waiting section,
        / so there will be no thread to send the signal to wake up other threads
        */
        turn = num-1;
        for (int i = 0; i < num; ++i) {
            conditions[i] = lockvar.newCondition();
        }

    }
    public void waitTurn(int id) {
        lockvar.lock();
        while (id != turn) {
            try {
                conditions[id].await();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
        lockvar.unlock();
    }

    public void signalDone(int id) {
        lockvar.lock();
        // TODO: Need to modify new variable here to allow one of the threads
        // blocked on the while to continue
        turn--;
        if (id != 0) {

        /* 
        / this should be conditions[turn].signal(), not conditions[id] 
        / because a thread cannot wake up themself,
        / when we use condition[turn] we are in thread 9 and we sent signal to wake up thread 8, 
        / and furthermore, turn is reduced value and wake up the next smaller thread.
        */
            conditions[turn].signal();
        }

        lockvar.unlock();
    }
}
import java.util.concurrent.locks.*;
导入java.util.concurrent.locks.Condition;
公共类监视器数组{
私钥锁;
私人条件[]条件;
私人内翻;
公共监视器阵列(int num){
this.lockvar=new ReentrantLock();
this.conditions=新条件[num];
/*
/转动值应为num-1(9),而不是num(10)
/因为如果turn=10,那么所有线程都将处于等待部分,
/因此,将没有线程发送信号来唤醒其他线程
*/
turn=num-1;
对于(int i=0;i
我已经找到了解决方案,我将在我的代码注释中给出我的解释

import java.util.concurrent.locks.*;
import java.util.concurrent.locks.Condition;

public class MonitorArray {

    private Lock lockvar;
    private Condition[] conditions;
    private int turn;

    public MonitorArray(int num) {
        this.lockvar = new ReentrantLock();
        this.conditions = new Condition[num];

        /*
        / the turn value should should be num-1(9) instead of num(10) 
        / because if turn = 10 so all threads will be in waiting section,
        / so there will be no thread to send the signal to wake up other threads
        */
        turn = num-1;
        for (int i = 0; i < num; ++i) {
            conditions[i] = lockvar.newCondition();
        }

    }
    public void waitTurn(int id) {
        lockvar.lock();
        while (id != turn) {
            try {
                conditions[id].await();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
        lockvar.unlock();
    }

    public void signalDone(int id) {
        lockvar.lock();
        // TODO: Need to modify new variable here to allow one of the threads
        // blocked on the while to continue
        turn--;
        if (id != 0) {

        /* 
        / this should be conditions[turn].signal(), not conditions[id] 
        / because a thread cannot wake up themself,
        / when we use condition[turn] we are in thread 9 and we sent signal to wake up thread 8, 
        / and furthermore, turn is reduced value and wake up the next smaller thread.
        */
            conditions[turn].signal();
        }

        lockvar.unlock();
    }
}
import java.util.concurrent.locks.*;
导入java.util.concurrent.locks.Condition;
公共类监视器数组{
私钥锁;
私人条件[]条件;
私人内翻;
公共监视器阵列(int num){
this.lockvar=new ReentrantLock();
this.conditions=新条件[num];
/*
/转动值应为num-1(9),而不是num(10)
/因为如果turn=10,那么所有线程都将处于等待部分,
/因此,将没有线程发送信号来唤醒其他线程
*/
turn=num-1;
对于(int i=0;i
您是否收到错误或所有线程都在等待?我想,由于id[0-9]和回合(10)从来都不匹配,后者正在发生。谢谢你,happyHelper!我所有的线程都在等待。但我认为我减少了signalDone()中的“turn”,这样它就应该匹配条件并逐个释放线程。这似乎是一个有趣的问题,所以我尝试通过一些小的调整来运行它,但类似的事情也在发生。线程不会被释放。如果我使用
signalAll()
,它就不需要信号,但可以工作。该信号正在唤醒一个与FirstWayer线程id不匹配的线程,我猜。您是遇到错误还是所有线程都在等待?我想,由于id[0-9]和回合(10)从来都不匹配,后者正在发生。谢谢你,happyHelper!我所有的线程都在等待。但是我认为我减少了signalDone()中的“turn”,这样它就应该匹配条件并逐个释放线程。这似乎是一个有趣的问题,所以我尝试了一些小的调整来运行它,但类似的事情