在fork/join部分的Java并发教程中,"computeDirectly"函数是如何通过"invokeAll"执行的?
In Java concurrency tutorial in fork/join section, how is the "computeDirectly" function executed via "invokeAll"?
在the fork/join chapter官方Java并发教程中,有以下部分示例代码。
我知道如果图像数组大小小于阈值 (100,000),则会直接计算 (computeDirectly
)。否则它会分成两半,并创建和调用两个 ForkBlur
对象 (invokeAll
)。我不明白的是 invokeAll
最终如何为这些片段执行 computeDirectly
函数。
对于大于阈值的数组,如何调用computeDirectly
函数? (它被分成几部分。)
public class ForkBlur extends RecursiveAction {
private int[] mSource;
private int mStart;
private int mLength;
private int[] mDestination;
// Processing window size; should be odd.
private int mBlurWidth = 15;
public ForkBlur(int[] src, int start, int length, int[] dst) {
mSource = src;
mStart = start;
mLength = length;
mDestination = dst;
}
protected void computeDirectly() {
int sidePixels = (mBlurWidth - 1) / 2;
for (int index = mStart; index < mStart + mLength; index++) {
// Calculate average.
float rt = 0, gt = 0, bt = 0;
for (int mi = -sidePixels; mi <= sidePixels; mi++) {
int mindex = Math.min(Math.max(mi + index, 0),
mSource.length - 1);
int pixel = mSource[mindex];
rt += (float)((pixel & 0x00ff0000) >> 16)
/ mBlurWidth;
gt += (float)((pixel & 0x0000ff00) >> 8)
/ mBlurWidth;
bt += (float)((pixel & 0x000000ff) >> 0)
/ mBlurWidth;
}
// Reassemble destination pixel.
int dpixel = (0xff000000 ) |
(((int)rt) << 16) |
(((int)gt) << 8) |
(((int)bt) << 0);
mDestination[index] = dpixel;
}
}
...
而这个单独的部分称它为:
protected static int sThreshold = 100000;
protected void compute() {
if (mLength < sThreshold) {
computeDirectly();
return;
}
int split = mLength / 2;
invokeAll(new ForkBlur(mSource, mStart, split, mDestination),
new ForkBlur(mSource, mStart + split, mLength - split,
mDestination));
}
这个
invokeAll(new ForkBlur(mSource, mStart, split, mDestination),
new ForkBlur(mSource, mStart + split, mLength - split,
mDestination));
最终调用 ForkBlur
的 compute
方法,如果您将其拆分到足够小的阈值,将通过 [=15= 执行 computeDirectly
] 这里的条件
if (mLength < sThreshold) {
computeDirectly();
return;
}
所以一个大任务被拆分成两个(或更多)较小的任务,这些任务可能会再次拆分,然后再拆分,直到任务小到 运行。
在the fork/join chapter官方Java并发教程中,有以下部分示例代码。
我知道如果图像数组大小小于阈值 (100,000),则会直接计算 (computeDirectly
)。否则它会分成两半,并创建和调用两个 ForkBlur
对象 (invokeAll
)。我不明白的是 invokeAll
最终如何为这些片段执行 computeDirectly
函数。
对于大于阈值的数组,如何调用computeDirectly
函数? (它被分成几部分。)
public class ForkBlur extends RecursiveAction {
private int[] mSource;
private int mStart;
private int mLength;
private int[] mDestination;
// Processing window size; should be odd.
private int mBlurWidth = 15;
public ForkBlur(int[] src, int start, int length, int[] dst) {
mSource = src;
mStart = start;
mLength = length;
mDestination = dst;
}
protected void computeDirectly() {
int sidePixels = (mBlurWidth - 1) / 2;
for (int index = mStart; index < mStart + mLength; index++) {
// Calculate average.
float rt = 0, gt = 0, bt = 0;
for (int mi = -sidePixels; mi <= sidePixels; mi++) {
int mindex = Math.min(Math.max(mi + index, 0),
mSource.length - 1);
int pixel = mSource[mindex];
rt += (float)((pixel & 0x00ff0000) >> 16)
/ mBlurWidth;
gt += (float)((pixel & 0x0000ff00) >> 8)
/ mBlurWidth;
bt += (float)((pixel & 0x000000ff) >> 0)
/ mBlurWidth;
}
// Reassemble destination pixel.
int dpixel = (0xff000000 ) |
(((int)rt) << 16) |
(((int)gt) << 8) |
(((int)bt) << 0);
mDestination[index] = dpixel;
}
}
...
而这个单独的部分称它为:
protected static int sThreshold = 100000;
protected void compute() {
if (mLength < sThreshold) {
computeDirectly();
return;
}
int split = mLength / 2;
invokeAll(new ForkBlur(mSource, mStart, split, mDestination),
new ForkBlur(mSource, mStart + split, mLength - split,
mDestination));
}
这个
invokeAll(new ForkBlur(mSource, mStart, split, mDestination),
new ForkBlur(mSource, mStart + split, mLength - split,
mDestination));
最终调用 ForkBlur
的 compute
方法,如果您将其拆分到足够小的阈值,将通过 [=15= 执行 computeDirectly
] 这里的条件
if (mLength < sThreshold) {
computeDirectly();
return;
}
所以一个大任务被拆分成两个(或更多)较小的任务,这些任务可能会再次拆分,然后再拆分,直到任务小到 运行。