錯誤程式
public class calculator extends recursivetask
@override
protected integer compute()
}else
return sum;
}}
(1)fork
1.基本作用
將任務放入任務佇列隊尾
2.原始碼
public final forkjointaskfork()
該方法屬於:forkjointask,也就是說this指向任務本身,將任務新增到任務佇列末尾
因為執行forkjointask的執行緒就是forkjoinworkerthread,所以可以呼叫其中的pushtask方法
/**
* pushes a task. call only from this thread.
** @param t the task. caller must ensure non-null.
*/final void pushtask(forkjointask<?> t)
}
其中有個成員變數queue,用來儲存和本執行緒對應的任務佇列
定義:
forkjointask<?> queue;
初始化:
protected void onstart()
接著繼續看pushtask
if ((s -= queuebase) <= 2)
pool.signalwork();
就是說當任務佇列中只有乙個任務時,從執行緒池中呼叫執行緒執行
(2)join
1.基本作用
阻塞當前執行緒,直到本任務執行完畢(相當於forkjointask版的thread.join)
2.原始碼
public final v join()
主要是為了看返回值,接著看dojoin
private int dojoin() catch (throwable rex)
if (completed)
return setcompletion(normal);
}return w.jointask(this);
}else
return externalawaitdone();
}
這裡先通過status判斷狀態
volatile int status; // accessed directly by pool and workers
private static final int normal = -1;
private static final int cancelled = -2;
private static final int exceptional = -3;
private static final int signal = 1;
也就是說<0的是已經執行完畢的,
這對於竊取非常重要
然後通過unpushtask取任務然後執行,看下unpushtask
final boolean unpushtask(forkjointask<?> t)
return false;
}
注意其中的
--s,也就是
說是從佇列尾取的任務
(3)分析
left.fork();
right.fork();
sum = left.join() + right.join();
由上面可知,這段**的意思就是:
1.把left放入任務佇列,right放入任務佇列。此時right在隊尾,left在倒數第二個
2.left.join(),因為當前right在隊尾,所以說取不出來!!!因而執行緒就會阻塞
正確的是呼叫invokeall,看下invokeall
public static void invokeall(forkjointask<?> t1, forkjointask<?> t2)
也就是說先把t2加入佇列中,然後直接執行t1,接著對t2執行join
對應上例就是:把right放入佇列尾部,然後left開始執行,最後對right進行join,直到left執行完畢才能執行(當然right可能被其他執行緒竊取,這樣通過狀態判斷就直接返回了)
更一般的
public static void invokeall(forkjointask<?>... tasks)
else if (i != 0)
t.fork();
else if (t.doinvoke() < normal && ex == null)
ex = t.getexception();
}for (int i = 1; i <= last; ++i)
}if (ex != null)
unsafe.throwexception(ex);
}
可以看到 i != 0 才進行fork,也就是說佇列中第乙個都是直接執行的,其他的以此fork,fork之後的任務之後進行join
(4)invoke
1.基本作用
直接執行任務
2.原始碼
public final v invoke()
再看下doinvoke
private int doinvoke() catch (throwable rex)
if (completed)
return setcompletion(normal);
else
return dojoin();
}
其中的exec()在recursivetask中
protected final boolean exec()
在recursiveaction中
protected final boolean exec()
也就是說直接執行了 JAVA中的Fork Join框架
fork join框架是executorservice介面的乙個實現,可以幫助開發人員充分利用多核處理器的優勢,編寫出並行執行的程式,提高應用程式的效能 設計的目的是為了處理那些可以被遞迴拆分的任務。fork join框架與其它executorservice的實現類相似,會給執行緒池中的執行緒分發任...
jquery中鏈式呼叫原理
1 鏈式呼叫 mybtn css width 100px css height 100px css background red 2 在對屬性進行操作時建議使用json形式控制樣式 mybtn css 3 事件中this的指向 事件中this的指向 jquery中提示了乙個方法,該方法可以將原生js...
jQuery中鏈式呼叫原理
1 鏈式呼叫 1 mybtn css width 100px 23 css height 100px 45 css background red 2 在對屬性進行操作時建議使用json形式控制樣式 1 mybtn css 3 事件中this的指向 事件中this的指向 jquery中提示了乙個方法,...