如何从多线程访问数组?

时间:2013-07-21 13:33:45

标签: java multithreading

简单来说,我的问题如下:

我有一个名为Test的类,它有3个双数组,分别命名为array1,array2,array3(假设它们具有相同的长度)。它有一个名为Estep的主要函数,我需要用多个函数实现这个函数穿线以提高速度。

在Estep中,我需要修改array1和array2,而array3仅用于读取。我定义一个名为which_array的指示符变量来指示要修改的数组。我将三个数组传递给Estep修改array1和array2。

我的代码如下,我测试它并且它工作正常,因为可以在Test class 中看到Estep中array1和array2的修改。但我仍然怀疑它是否绝对正确。我想知道是否应该在Test类中将 volatile 添加到三个array1中,还是需要一些同步机制?

任何建议都将不胜感激!

public class Test{

    double[] array1;
    double[] array2;
    double[] array3;
    //for simplifization, I omitted the code for allocation and initialization of the the arrays.
    public void EstepInTest()
    {
        final CountDownLatch countdown = new CountDownLatch(2);

    Estep modifyArray1 = new Estep(array1, array2, array3, 1,countdown);
    Thread t1 = new Thread( firstHalf);
    t1.start();

    Estep modifyArray2 = new Estep(array1, array2, array3, 2,countdown);    
        Thread t2 = new Thread(secondHalf);
    t2.start();

    try{
    countdown.await();
    }catch (InterruptedException e) {
        e.printStackTrace();
    }

        //do next things
    }

}

class Estep implements Runnable{

    double[] array1;
    double[] array2;
    double[] array3;
    int which_array;

    Estep(double[] array1, double[] array2, double[] array3, int which_array, CountDownLatch cd)
    {
        this.array1 = array1;
        this.array2 = array2;
        this.array3 = array3;
        this.which_array = which_array;
        this.cd = cd;
    }

    public void run(){

        if( this.which_array == 1){
           for( int i = 0; i < array1.length; ++i )
           {   
               array1[i] = array1[i] + array3[i];
           }  
        }else{
           for( int i = 0; i < array2.length; ++i )
           {   
               array2[i] = array2[i] + array3[i];
           }
        }
        cd.countDown();
   }

3 个答案:

答案 0 :(得分:2)

是对的。 CountDownLatch.await()保证在返回之前完成所有操作发生 - 在返回之后完成所有操作。

如果您只是简单地将数组传递给Estep构造函数,而不是传递两个数组,并使用一个幻数来指示要修改哪个数组,那么您的代码会更清晰,更短。

编辑:

关于对array3的访问权限,它也是安全的,因为正如the documentation of the concurrent package中所述,在之前调用start线程启动线程中的任何操作。因此,两个线程将看到在启动它们之前对array3所做的每个修改。

另外,请注意,使数组volatile只会使数组引用为volatile。它不会使其元素易变。

答案 1 :(得分:0)

考虑将只有两个数组传递给Estep,其中一个数据用于下一步的修改。在这种情况下,您不需要冗余的哪个数组变量以及运行

中的常规代码

答案 2 :(得分:0)

我不熟悉倒计时闩锁。

您还可以同步数组对象本身。您可以通过将数组设置为要在getter和setter中同步的监视器对象来完成此操作。这样可以防止对影响当前行的数组的任何访问,并阻止以异步方式发生最少量的代码。

// In the original test class
public int getArray1(int index) {

   unsynchronized_statements...

   int result;
   synchronized(array1) {
       result = array1[index]...
   }
   return result;
}