的静态变量的使用,同时使用叉加入

的静态变量的使用,同时使用叉加入

问题描述:

问题陈述: - //这是一个示例,实际阵列尺寸很大的静态变量的使用,同时使用叉加入

假设有A级

public class A{ 
    public static int aa[]=new int[5]; 
    public computeaa(){ 
     for(int i=0;i<5;i++) 
      aa[i] = useaa(i); 
    } 
    //this below function can compute aa[i] value 
    public int useaa(int i){ 
      if(i<=0) 
       return 1; 
      if(aa[i]!=0) 
       return aa[i]; 
      else 
       return useaa[i-1]+useaa[i-2]; 
    } 
} 

而且RecursiveAction B类

@Override 
protected void compute() { 
    // TODO Auto-generated method stub 
    A z=new A(); 
    A.computeaa(); 
} 
public static void main(String[] args) { 
    List<B> tasks =new ArrayList<B>(); 
    for(int i=1; i<=2; i++){ 
     //There is 2 fork will created 
     B =new B(); 
     tasks.add(B); 
     B.fork(); 
    } 
    if (tasks.size() > 0) { 
     for (B task : tasks) { 
      task.join(); 
     } 
    } 
} 

怀疑?

  1. 假设叉1计算静态变量AA [2],并且假设当叉2将计算AA [2],可以在此叉2得到的值AA [2],其通过与fork1或计算它会单独计算?

  2. 据我了解,fork 2在某些情况下很容易访问fork1的aa,假设fork 2想要计算aa [3],它可以得到已经由fork 1计算出来的值。但是问题是假设fork 1将尝试计算aa [4],计算aa [4],它需要aa [3],已经计算出叉1,但如果fork 1试图获得aa [3],它可能会有可能,但偶然它会得到访问权叉1的aa [3],这是不计算...再次造成一团糟。

我很谜题叉联接好心帮

有简单的问题,我想计算一些阵列所使用的同一个班级,但是在建立一个以上的对象我想使用相同的数组,这是由其他对象计算,以便减少我的计算时间。
如何复制或获取该数组到另一个对象,以便该对象不需要计算?

+1

如何使用['AtomicIntegerArray'](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicIntegerArray.html)? –

+0

提示:当您花时间为我们创建[mcve]时:请遵循遵循Java命名约定的正确有意义的名称。其他任何东西都会显着降低您为我们组合的源代码的价值。含义 - 单独使用a和aa和useaa会使您的代码几乎无法理解。 – GhostCat

+0

除此之外:没有人告诉过你,使用静态在oop中通常是不好的做法吗? – GhostCat

  1. 假设叉1计算静态变量AA [2],并且假设当叉2将计算AA [2],可以在此叉2得到的值AA [2] ,其通过与fork1计算或它会分开计算?

假设在不同线程中运行两个B任务 - 在其上选择不行使任何控制 - 这些两个线程都访问同一阵列对象的相同元件而没有任何同步。任何一个线程都可以读取另一个写入的值。而且,如果他们再次访问该数组元素,他们可能会读取不同的值。该程序没有正确同步,因此不能保证顺序一致性。

  1. 通过我的理解叉2在某些情况下很容易地访问与fork1的AA,假设叉2想计算AA [3],它可以得到其中 已经由计算的值fork 1.但是问题是假设fork 1 将尝试计算aa [4],计算aa [4]时,它需要aa [3],其中fork 1已经计算出来了,但如果fork 1试图得到 aa [3],但偶然它得到aa [3]叉1的访问,这是 不计算...再次造成一团糟。
开始=“2”>

是的,你的判断是正确的 - 关于可能的行为和关于它是一团糟。

有简单的问题,我想计算一些阵列所使用的 同一个班级,但是在建立一个以上的对象我想用它被其他物体计算的 同一阵列,这样我的计算 时间减少。我如何复制或获取该数组到另一个对象,所以 ,这个对象不需要计算?

在某些情况下,您可能会有不同的线程并行计算数组的不相交部分。然而,由于数据之间的依赖关系,问题中提出的计算不适用于此。因为在计算前2之前没有可以计算过去索引1的元素,所以元素的计算需要以某种方式进行序列化。你不能通过将单个线程用于工作来实现这一点。

完成此类计算后,您可以在线程之间共享已初始化的数组,只要它们以某种方式与计算完成同步。如果任何线程在初始计算完成后修改了阵列,则会应用其他同步要求。

您的具体情况有点棘手,因为很少有具有同步意义的动作存在。特别是,你的数组元素不是(也不可能是)final,你不能确信你的任务运行的线程只在你使用fork();如果你有后者,那么主线程之前做的所有事情都会自动与任务的工作同步。正因为如此,你可能会做这样的事情:

public class A { 
    // not static: 
    public int aa[] = new int[5]; 

    public void computeAa() { 
     aa[0] = 1; 
     aa[1] = 1; 

     for (int i = 2; i < aa.length; i++) { 
      aa[i] = aa[i - 1] + aa[i - 2]; 
     } 
    } 

    public int getAa(int i) { 
     return (i < 0) ? 1 : aa[i]; 
    } 
} 

public class B extends RecursiveAction { 

    private A myA; 

    public RecursiveAction(A a) { 
     myA = a; 
    } 

    @Override 
    protected void compute() { 
     synchronized (myA) { 
      // ensure that myA's initialization is complete 
      while (myA.aa[0] == 0) { 
       // not yet initialized 
       myA.wait(); 
      } 
     } 
     // ... do something with myA (without modifying it) ... 
    } 

    public static void main(String[] args) { 
     A theA = new A(); 

     synchronized(theA) { 
      // synchronize the initialization of theA, because other threads will 
      // check it 
      theA.computeAa(); 

      // wake up any threads waiting on the initialization 
      theA.notifyAll(); 
     } 

     List<B> tasks = new ArrayList<B>(); 

     for(int i = 1; i <= 2; i++){ 
      //There is 2 fork will created 
      B = new B(theA); 
      tasks.add(B); 
      B.fork(); 
     } 

     for (B task : tasks) { 
      task.join(); 
     } 
    } 
} 

注意这里说的主线程创建的A实例和分叉任何任务之前对其进行初始化。它为每个B提供这个实例(因此它们共享它)。

+0

computeAa中是否需要在main方法中同步,因为其他线程只会在for循环中的程序计数器时才会播放? –

+0

答案看起来很完美,你能否清楚我的疑问。 –

+0

@MukeshGupta,考虑到所涉及的类只有可用的API文档没有理由假设可以安全地省略'synchronized'块,'wait()'或者'notifyAll()'中的任何一个。特别是,主线程中'fork()'调用的相对时间是不够的,因为不同的线程可以看到线程间的动作,例如以不同顺序修改共享变量。两个同步块一起,以及'wait()'和'notifyAll()'的特殊用法确保了适当的全局线程化操作顺序。 –