Java 如何从多线程访问阵列?

Java 如何从多线程访问阵列?,java,multithreading,Java,Multithreading,简单来说,我的问题如下: 我有一个名为Test的类,它有3个双数组,分别名为array1、array2、array3(假设它们的长度相同)。它有一个名为Estep的主函数,我需要用多线程来实现这个函数以提高速度 在Estep中,我需要修改array1和array2,而array3仅用于读取。我定义了一个名为which_array的指示符变量来指示要修改的数组。我将这三个数组传递给Estep并修改array1和array2 我的代码如下,我对它进行了测试,它运行良好,因为在测试类中可以看到Este

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

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

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

我的代码如下,我对它进行了测试,它运行良好,因为在测试类中可以看到Estep中对array1和array2的修改。但我仍然怀疑它是否绝对正确。我想知道是应该在测试类的三个数组1中添加volatile,还是需要一些同步机制

任何建议都将不胜感激

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();
   }
公共类测试{
双[]阵列1;
双[]阵列2;
双[]阵列3;
//为了简化,我省略了分配和初始化数组的代码。
公共无效测试()
{
最终倒计时闩锁倒计时=新倒计时闩锁(2);
Estep modifyArray1=新的Estep(array1,array2,array3,1,倒计时);
螺纹t1=新螺纹(上半部分);
t1.start();
Estep modifyArray2=新的Estep(阵列1,阵列2,阵列3,2,倒计时);
螺纹t2=新螺纹(第二个半螺纹);
t2.start();
试一试{
倒计时;
}捕捉(中断异常e){
e、 printStackTrace();
}
//做下一件事
}
}
类Estep实现可运行{
双[]阵列1;
双[]阵列2;
双[]阵列3;
整型数组;
Estep(双[]数组1,双[]数组2,双[]数组3,整数数组,倒计时锁存cd)
{
this.array1=array1;
this.array2=array2;
这个数组3=数组3;
this.which_array=哪个_array;
this.cd=cd;
}
公开募捐{
if(this.which_数组==1){
对于(int i=0;i
这是正确的。
CountDownLatch.await()
保证在它返回之前所做的一切都发生在它返回之后所做的一切之前

如果您只是将要修改的数组传递给Estep构造函数,而不是传递两个数组和一个幻数来指示要修改的数组,那么您的代码将更干净、更短

编辑:

关于对
array3
的访问,它也是安全的,因为如中所述,对线程的
start
调用发生在已启动线程中的任何操作之前。因此,这两个线程将看到在启动它们之前对
array3
所做的每一次修改


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

请考虑只将两个数组传递给Estep,一个用于修改,另一个用于读取。在这种情况下,您不需要冗余哪个数组变量以及运行中的常规代码。

我不太熟悉倒计时闩锁

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

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

   unsynchronized_statements...

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

谢谢你的帮助。我的代码只是为了演示,因为每个数组的修改逻辑不同,所以我传递了两个数组和一个幻数。为了验证,我不需要向array3和其他两个数组添加volatile,因为这两个线程同时访问array3。正如我对j中多线程的理解一样ava非常有限,所以如果我问一个愚蠢的问题,请不要介意,谢谢你的建议,因为我使用两个线程分别修改两个数组,所以保证只有一个线程同时修改特定数组,所以在我的问题设置中不必同步数组吗?好的,我想在这种情况下,你需要应该没问题,因为wait方法应该在您准备好之前阻止主类使用数组。