Java数组线程安全吗?

use*_*591 1 java multithreading synchronization thread-safety java-threads

就像标题一样,给定 2 个数组int[] a,由两个线程共享,每个线程以第一个数组的每个元素都是第二个数组的对应元素int[] b的方式重新排列两个数组的元素,输出似乎总是正确的,而不需要同步需求<=a[i] <= b[i]

public class MyClass {

    int[] a = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    int[] b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    class MyThread extends Thread {
        public void run() {
                for (int i = 0; i < a.length; i++) {
                    if (a[i] > b[i]) {
                        int temp = b[i];
                        b[i] = a[i];
                        a[i] = temp;
                    }
                }
        }
    }

    public static void main(String[] args) {

        MyClass myClass = new MyClass();

        MyThread t1 = myClass.new MyThread();
        MyThread t2 = myClass.new MyThread();

        t1.start();
        t2.start();

        while (t1.isAlive() | t2.isAlive()) {
            System.out.println("waiting");
        }

        System.out.println(Arrays.toString(myClass.a));
        System.out.println(Arrays.toString(myClass.b));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的输出(在多次运行中)我应该认为这只是运气还是我遗漏了一些东西?

a = [0, 1, 2, 3, 4, 4, 3, 2, 1, 0]
b = [9, 8, 7, 6, 5, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

eri*_*son 5

这就是运气。除非线程以某种方式同步,否则不保证一个线程的写入对其他线程可见。数组也不例外。

这里有一种AtomicIntegerArray类型可以帮助您。

虽然将数组字段声明为volatile不扩展到数组的元素,但可能有一种方法可以使用它来建立“发生之前”关系。我必须仔细考虑一下,但如果它确实有效,那么它会相当脆弱,因为稍微改变用法可能会产生并发错误。