java - 原子整数不当行为

标签 java multithreading atomic

我有一个练习:给定一个 AtomicIntegers 矩阵(初始化为 0),我必须为每行运行一个线程,为每列运行一个线程,在行上我减 1,在列上我加 1,所以最后矩阵应该保持原样。问题是矩阵改变了!这是代码: 该对象采用矩阵、一个 boolean 值(告诉他要对列或行进行操作)以及必须操作的列/行的索引。

import java.util.concurrent.atomic.AtomicInteger;

public class FifthExerciseSafe implements Runnable{
    private Thread thread;
    private boolean onRows;//tells if the object operates on the rows or on the columns
    private AtomicInteger[][] matrix;
    private int index;

public FifthExerciseSafe(AtomicInteger[][] matrix, boolean onRows, int index){
    this.matrix = matrix;
    this.onRows = onRows;
    this.index = index;
}

public void start(){
    thread = new Thread(this);
    thread.start();
}

public boolean isOnRows() {
    return onRows;
}

public void setOnRows(boolean onRows) {
    this.onRows = onRows;
}

public AtomicInteger[][] getMatrix() {
    return matrix;
}

public void setMatrix(AtomicInteger[][] matrix) {
    this.matrix = matrix;
}

@Override
public void run() {
    if (this.onRows){
        for(int i = 0; i < matrix[index].length; i++){
            matrix[index][i].decrementAndGet();
        }
    } else {            
        for(int i = 0; i < matrix.length; i++){
            matrix[i][index].incrementAndGet();
        }
    }
}//run

public static void main(String args[]){
    AtomicInteger[][] m = new AtomicInteger[3][3];
    for (int i = 0; i < m.length; i++){
        for(int j = 0; j < m.length; j++){
            m[i][j]= new AtomicInteger(0);
        }
    }

    for(int i = 0; i < 3; i++){//I create 6 objects, 3 for columns and 3 for rows
        FifthExerciseSafe fes1 = new FifthExerciseSafe(m, true, i);
        FifthExerciseSafe fes2 = new FifthExerciseSafe(m, false, i);
        fes1.start();
        fes2.start();
    }
    for(int i = 0; i < m.length; i++){
        for(int j = 0; j < m.length; j++){
            System.out.print(m[i][j]+" ");
        }
    }
}//main
}

输出应该是: 000000 但有时是: -100-100-1-10

它只发生在配备 Intel Atom 的上网本上,在配备 Core Duo 的台式机上我还没有看到它,但我想知道它是否也可能发生在那里。

最佳答案

您已经启动了线程,但在继续打印矩阵之前您永远不会等待它们完成。您需要为每个启动的线程使用 Thread.join,这将阻塞直到线程完成。只有这样才能安全地打印结果。例如,引入一个ArrayList,在其中添加您启动的Thread的所有实例,然后有一个单独的for 循环,在每个实例上调用 join

关于java - 原子整数不当行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13471036/

相关文章:

java - 如何在启动时验证 Spring Data JPA 查询?

ios - 在 NSoperationQueue 上调用 -(void) cancelAllOperations 不会设置队列中存在的 NSOperation 的 isCancelled 属性

Java同步线程

c++ - 是否有可能在 C++ 中使用 std::atomic_flag 获得线程锁定机制?

c# - 工作单元模式如何容纳对新聚合的引用?

java - ArrayList 抛出语法错误 "Unknown class"

java - 如何从 Eclipse 编辑器 (Java) 中快速查找接口(interface)方法的参数?

java - 定义局部变量时哪个顺序更好?

multithreading - `getErrno` 和线程

c - 使用 CAS 以原子方式递增两个整数