本文主要根据《Java程序员修炼之道》整理的代码笔记片段
采用“工作窃取”的算法解决大小不同任务所导致的调度问题
场景:
模拟大量简单对象的运动
日志文件分析
从输入中计数的数操作,如mapreduce java jdk排序算法SortTask采用该框架
RecursiveAction 继承ForkJoinTask<Void>
public class MicroBlogUpdateSorter extends RecursiveAction {
private static final long serialVersionUID = 2077227050172847747L;
private static final int SMALL_ENOUGH = 32;
private final Update[] updates;
private final int start, end;
private final Update[] result;
public MicroBlogUpdateSorter(Update[] updates_) {
this(updates_, 0, updates_.length);
}
public MicroBlogUpdateSorter(Update[] upds_, int startPos_, int endPos_) {
start = startPos_;
end = endPos_;
updates = upds_;
result = new Update[updates.length];
}
private void merge(MicroBlogUpdateSorter left_, MicroBlogUpdateSorter right_) {
int i = 0;
int lCt = 0;
int rCt = 0;
while (lCt < left_.size() && rCt < right_.size()) {
result[i++] = (left_.result[lCt].compareTo(right_.result[rCt]) < 0) ? left_.result[lCt++]
: right_.result[rCt++];
}
while (lCt < left_.size())
result[i++] = left_.result[lCt++];
while (rCt < right_.size())
result[i++] = right_.result[rCt++];
}
public int size() {
return end - start;
}
public Update[] getResult() {
return result;
}
@Override
protected void compute() {
if (size() < SMALL_ENOUGH) {
System.arraycopy(updates, start, result, 0, size());
Arrays.sort(result, 0, size());
} else {
int mid = size() / 2;
MicroBlogUpdateSorter left = new MicroBlogUpdateSorter(updates, start, start + mid);
MicroBlogUpdateSorter right = new MicroBlogUpdateSorter(updates, start + mid, end);
invokeAll(left, right);
merge(left, right);
}
}
}
public class UpdateSorterMain {
public static void main(String[] args) {
List<Update> lu = new ArrayList<Update>();
String text = "";
final Update.Builder ub = new Update.Builder();
final Author a = new Author("Tallulah");
for (int i = 0; i < 256; i++) {
text = text + "X";
long now = System.currentTimeMillis();
lu.add(ub.author(a).updateText(text).createTime(now).build());
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
}
Collections.shuffle(lu);
Update[] updates = lu.toArray(new Update[0]); // Avoid allocation by passing
// zero-sized array
MicroBlogUpdateSorter sorter = new MicroBlogUpdateSorter(updates);
ForkJoinPool pool = new ForkJoinPool(4);
pool.invoke(sorter);
for (Update u : sorter.getResult()) {
System.out.println(u);
}
}
}