【问题标题】:Why CyclicBarrier doesn't always work as intended in my program?为什么 CyclicBarrier 在我的程序中并不总是按预期工作?
【发布时间】:2018-10-22 19:17:41
【问题描述】:

我做了一个简单的程序来计算矩阵中的行总和。我想同时这样做,所以我使用了 CyclicBarrier。有时它会按预期工作,但有时会出现小错误,就像程序漏掉一两个数字一样。

这是我的代码:

package synchronizacja;
import java.util.concurrent.CyclicBarrier;
public class SumyWierszamiSekwencyjnie {
private static final int ROWS = 10;
private static final int COLUMNS = 100;
private static  int sum;
private static CyclicBarrier barrier = new CyclicBarrier(COLUMNS, new Tmp());

private static class Tmp implements Runnable {
    @Override
    public void run() {
        System.out.println("The sum is: " + sum);
        sum = 0;
    }
}

private static class CountByColumns implements Runnable {
    private void CriticalSection(int wiersz) {
        sum += wiersz;
    }
    @Override
    public void run() {
        for (int i = 0; i < ROWS; i++) {
           CriticalSection(i);
           try { barrier.await(); }
           catch (Exception e) { System.out.println("Exception"); }
        }

    }
}

public static void main(String[] args) {
    for (int i = 0; i < COLUMNS; i++) {
        new Thread(new CountByColumns()).start();
    }
}
}

输出应该是

The sum is: 0
The sum is: 100
The sum is: 200
The sum is: 300
The sum is: 400
The sum is: 500
The sum is: 600
The sum is: 700
The sum is: 800
The sum is: 900

有时确实如此,但更多时候它会显示类似的东西

The sum is: 0
The sum is: 100
The sum is: 200
The sum is: 297
The sum is: 400
The sum is: 500
The sum is: 600
The sum is: 700
The sum is: 800
The sum is: 900

为什么会这样?我在想这可能是因为 Tmp 类中的 run() 不必是原子的,所以当前线程可能会在将 sum 设置为 0 之前跳到计算另一行的总和。如果是这样,我该如何防止这种情况?

【问题讨论】:

    标签: concurrency java.util.concurrent


    【解决方案1】:

    我在想这可能是因为 Tmp 类中的 run() 不必是原子的,所以当前线程可能会在将 sum 设置为 0 之前跳过计算另一行的总和。

    我不这么认为,the javadoc of CB.await 指定

    如果当前线程是最后到达的线程,并且在构造函数中提供了非空屏障动作,则当前线程在允许其他线程继续之前运行该动作。

    有两个问题,第一个是潜在的多核可见性 执行屏障操作的线程可能还没有看到 sum 的变化,因为它没有在核心本地缓存中更新。 此外, += 运算符不是原子的,因此它可能会从 sum 中读取 20 并将其“2”添加到其中,并将 22 写入 sum,即使另一个线程在读取和写入之间将值更改为 23。 要解决这两个问题,您需要使用 AtomicInteger 或 Varhandles(volatile 仅修复可见性问题。Here are more information about atomic variables

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-28
      相关资源
      最近更新 更多