[英]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計算靜態變量aa [2],並且假設當分叉2將要計算aa [2]時,此分叉2能否獲得由fork1計算的值aa [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計算靜態變量aa [2],並且假設當分叉2將要計算aa [2]時,此分叉2能否獲得由fork1計算的值aa [2]還是將其單獨計算?
假設這兩個B
任務在不同的線程中運行-您選擇不對它們執行任何控制-這兩個線程正在訪問同一數組對象的同一元素而沒有任何同步。 每個線程都可以讀取另一個線程寫入的值。 此外,如果他們再次訪問該數組元素,則它們可能會讀取不同的值。 程序未正確同步,因此不能保證順序一致性。
- 據我了解,在某些情況下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.