Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.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/6/multithreading/4.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_Thread Safety - Fatal编程技术网

Java 我的代码是否处于死锁状态?

Java 我的代码是否处于死锁状态?,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,在编译下面的代码时,它似乎处于死锁状态,我不知道如何修复它。我试图将管道作为一系列线程作为缓冲区连接在一起,每个线程都可以读取管道中的前一个节点,并最终写入下一个节点。总体目标是将随机生成的数据数组列表分散到10个线程上,并对其进行排序 class Buffer{ // x is the current node private int x; private boolean item; private Lock lock = new ReentrantLo

在编译下面的代码时,它似乎处于死锁状态,我不知道如何修复它。我试图将管道作为一系列线程作为缓冲区连接在一起,每个线程都可以读取管道中的前一个节点,并最终写入下一个节点。总体目标是将随机生成的数据数组列表分散到10个线程上,并对其进行排序

    class Buffer{
    // x is the current node
    private int x;
    private boolean item;
    private Lock lock = new ReentrantLock();
    private Condition full = lock.newCondition();
    private Condition empty = lock.newCondition();

    public Buffer(){item = false;}

    public int read(){
        lock.lock();
        try{
          while(!item)
             try{full.await();}
             catch(InterruptedException e){}
          item = false;
          empty.signal();
          return x;
     }finally{lock.unlock();}
    }

    public void write(int k){
        lock.lock();
        try{
        while(item)
           try{empty.await();}
           catch(InterruptedException e){}
        x = k; item = true;
        full.signal();
      }finally{lock.unlock();}

  }
}

class Pipeline extends Thread {

    private Buffer b;
    //private Sorted s;
    private ArrayList<Integer> pipe; // array pipeline
    private int ub; // upper bounds
    private int lb; // lower bounds

    public Pipeline(Buffer bf, ArrayList<Integer> p, int u, int l) {
        pipe = p;ub = u;lb = l;b = bf;//s = ss;
    }

    public void run() {
        while(lb < ub) {
            if(b.read() > pipe.get(lb+1)) {
                b.write(pipe.get(lb+1));
            }

            lb++;
        }

        if(lb == ub) {
            // store sorted array segment
            Collections.sort(pipe);
            new Sorted(pipe, this.lb, this.ub);
        }
    }

}

class Sorted {

    private volatile ArrayList<Integer> shared;
    private int ub;
    private int lb;

    public Sorted(ArrayList<Integer> s, int u, int l) {
        ub = u;lb = l;shared = s;
        // merge data to array from given bounds
    }
}

class Test1 {
    public static void main(String[] args) {


        int N = 1000000;
        ArrayList<Integer> list = new ArrayList<Integer>();

        for(int i=0;i<N;i++) {
            int k = (int)(Math.random()*N);
            list.add(k);
        }

        // write to buffer
        Buffer b = new Buffer();
        b.write(list.get(0));

        //Sorted s = new Sorted();

        int maxBuffer = 10;
        int index[] = new int[maxBuffer+1];
        Thread workers[] = new Pipeline[maxBuffer];

        // Distribute data evenly over threads
        for(int i=0;i<maxBuffer;i++) 
            index[i] = (i*N) / maxBuffer;

        for(int i=0;i<maxBuffer;i++) {
            // create instacen of pipeline
            workers[i] = new Pipeline(b,list,index[i],index[i+1]);
            workers[i].start();
        }

        // join threads
        try {
            for(int i=0;i<maxBuffer;i++) {
                workers[i].join();
            }
        } catch(InterruptedException e) {}

        boolean sorted = true;

        System.out.println();
        for(int i=0;i<list.size()-1;i++) {
            if(list.get(i) > list.get(i+1)) {
                sorted = false;
            }
        }

        System.out.println(sorted);
    }
}

启动run方法时,所有线程都将阻塞,直到第一个线程达到full.await。然后一个接一个地,所有线程都将到达full.wait。他们将等待这个信号

然而,full.signal发生的唯一地方是在其中一个读取方法完成之后。 由于该信号从未触发,因此无法到达该代码,因此所有线程都在等待

简而言之,只有在1次读取完成后,写入才会触发。 如果你颠倒逻辑,开始清空,用信号等写缓冲区,然后线程尝试读取,我希望它会工作

一般来说,您希望在读取管道之前先将其写入管道。或者没有什么可读的

我希望我没有误读您的代码,但这是我在第一次扫描时看到的。

您的缓冲区类在读写模式之间切换。每次读取之后都必须有一次写入,然后是读取,依此类推

最初在main方法中写入缓冲区

现在,您的一个线程在Pipelinerun中到达ifb.read>pipe.getlb+1{。如果该条件的计算结果为false,则不会写入任何内容。而且由于每个其他线程都必须是相同的ifb.read,因此您最终会遇到无法进行的所有读取线程。您必须在else分支中写入或允许多次读取