簡體   English   中英

使用Fork-Join時的靜態變量用法

[英]Static variable usage while using Fork-Join

問題陳述:-//這是一個示例,實際數組大小非常大

假設有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能否獲得由fork1計算的值aa [2]或將單獨計算?

  2. 據我了解,在某些情況下fork 2可以輕松訪問fork1的aa,假設fork 2要計算aa [3],它可以獲取已經由fork 1計算的值。但是問題在於,假設fork 1將嘗試計算aa [4],要計算aa [4],需要aa [3],叉子1已經計算過了,但是如果叉子1嘗試獲取aa [3],它是否有可能,但是偶然地它獲得了aa [3]的訪問權沒有計算的叉子1的...再次造成混亂。

我很困惑,請加入fork

有一個簡單的問題,我想計算一個由同一類使用的數組,但是在創建多個對象的同時,我想使用由另一個對象計算的同一數組,從而減少了計算時間。
我如何才能將該數組復制或獲取到另一個對象,以便該對象不需要計算?

  1. 假設分叉1計算靜態變量aa [2],並且假設當分叉2將要計算aa [2]時,此分叉2能否獲得由fork1計算的值aa [2]還是將其單獨計算?

假設這兩個B任務在不同的線程中運行-您選擇不對它們執行任何控制-這兩個線程正在訪問同一數組對象的同一元素而沒有任何同步。 每個線程都可以讀取另一個線程寫入的值。 此外,如果他們再次訪問該數組元素,則它們可能會讀取不同的值。 程序未正確同步,因此不能保證順序一致性。

  1. 據我了解,在某些情況下fork 2可以輕松訪問fork1的aa,假設fork 2要計算aa [3],它可以獲取已經由fork 1計算的值。但是問題在於,假設fork 1將嘗試計算aa [4],要計算aa [4],需要aa [3],叉子1已經計算過了,但是如果叉子1嘗試獲取aa [3],它是否有可能,但是偶然地它獲得了aa [3]的訪問權沒有計算的叉子1的...再次造成混亂。

是的,您做出正確的判斷-無論是關於可能的行為還是一團糟。

有一個簡單的問題,我想計算一個由同一類使用的數組,但是在創建多個對象的同時,我想使用由另一個對象計算的同一數組,從而減少了計算時間。 我如何才能將該數組復制或獲取到另一個對象,以便該對象不需要計算?

在某些情況下,您可能有不同的線程並行計算數組的不相交部分。 但是,由於數據之間的依賴性,問題中提出的計算不適合該計算。 由於在計算前一個索引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提供實例(因此他們共享它)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM