首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CyclicBarrier代码不工作?

CyclicBarrier代码不工作?
EN

Stack Overflow用户
提问于 2013-06-17 00:17:58
回答 1查看 262关注 0票数 0

为了更好地理解它,我从oracle page获取了CyclicBarrier代码。我修改了它,现在有一个疑问。下面的代码不会终止,但如果我取消对Thread.sleep条件的注释,它会工作得很好。

代码语言:javascript
复制
import java.util.Arrays;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

class Solver {
    final int N;
    final float[][] data;
    boolean done = false;
    final CyclicBarrier barrier;

    class Worker implements Runnable {
        int myRow;

        Worker(int row) {
            myRow = row;
        }

        public void run() {
            while (!done) {
                processRow(myRow);

                try {
                    barrier.await();
                } catch (InterruptedException ex) {
                    return;
                } catch (BrokenBarrierException ex) {
                    return;
                }
            }
            System.out.println("Run finish for " + Thread.currentThread().getName());
        }

        private void processRow(int row) {

            float[] rowData = data[row];

            for (int i = 0; i < rowData.length; i++) {
                rowData[i] = 1;
            }

            /*try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            done = true;
        }
    }

    public Solver(float[][] matrix) {
        data = matrix;
        N = matrix.length;
        barrier = new CyclicBarrier(N, new Runnable() {
            public void run() {
                for (int i = 0; i < data.length; i++) {
                    System.out.println("Data " + Arrays.toString(data[i]));
                }

                System.out.println("Completed:");
            }
        });
        for (int i = 0; i < N; ++i)
            new Thread(new Worker(i), "Thread "+ i).start();
    }
}

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

        float[][] matrix = new float[5][5];

        Solver solver = new Solver(matrix);
    }
}

为什么在上面的代码中需要Thread.sleep?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-17 01:12:23

我没有运行你的代码,但是可能有一个竞态条件,下面是一个揭示它的场景:

当启动第一个线程时,它会在一段时间内运行,这段时间足以让它完成processRow方法调用,因此它将done设置为true,然后在屏障上等待

  • 其他线程开始,但它们看到所有都是“完成”的,所以它们不会进入循环和屏障,它们永远不会在屏障上等待,并且end directly

  • the 永远不会被激活,因为N个线程中只有一个线程已经到达it

  • deadlock

为什么它与睡眠一起工作

  • 当其中一个线程开始休眠时,让其他线程先休眠,然后再将工作标记为“完成”
  • 其他线程有足够的时间工作,并且可以达到阈值
  • 2秒基本上足以让5个线程结束不应超过10ms的处理

但请注意,如果你的系统是超载的,它可能会死锁:

  • first starts to
    • OS scheduler让另一个应用程序在超过2秒的时间内工作
    • 操作系统调度器返回到您的应用程序,线程调度器再次选择第一线程,让它终止,将完成<>e144<代码>e245<代码>E146再次设置为true
    • and here < => <代码>E150死锁<代码>E251太<代码>H252<代码>F253

和一种可能的解决方案(对不起,未经过测试):

为do/ while 循环更改while循环:

代码语言:javascript
复制
do
{
    processRow(myRow);

    ...
}
while (!done);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17135293

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档