fjtask.java
来自「采用JAVA开发」· Java 代码 · 共 532 行 · 第 1/2 页
JAVA
532 行
* such condition is built-in: join() repeatedly yields until a task
* has terminated after producing some needed results. You can also
* use yield to wait for callbacks from other FJTasks, to wait for
* status flags to be set, and so on. However, in all these cases,
* you should be confident that the condition being waited for will
* occur, essentially always because it is produced by
* a FJTask generated by the current task, or one of its subtasks.
*
* @exception ClassCastException if caller thread is not
* running in a FJTaskRunner thread.
**/
public static void yield() { getFJTaskRunner().taskYield(); }
/**
* Yield until this task isDone.
* Equivalent to <code>while(!isDone()) yield(); </code>
* @exception ClassCastException if caller thread is not
* running in a FJTaskRunner thread.
**/
public void join() { getFJTaskRunner().taskJoin(this); }
/**
* Immediately execute task t by calling its run method. Has no
* effect if t has already been run or has been cancelled.
* It is equivalent to calling t.run except that it
* deals with completion status, so should always be used
* instead of directly calling run.
* The method can be useful
* when a computation has been packaged as a FJTask, but you just need to
* directly execute its body from within some other task.
**/
public static void invoke(FJTask t) {
if (!t.isDone()) {
t.run();
t.setDone();
}
}
/**
* Fork both tasks and then wait for their completion. It behaves as:
* <pre>
* task1.fork(); task2.fork(); task2.join(); task1.join();
* </pre>
* As a simple classic example, here is
* a class that computes the Fibonacci function:
* <pre>
* public class Fib extends FJTask {
*
* // Computes fibonacci(n) = fibonacci(n-1) + fibonacci(n-2); for n> 1
* // fibonacci(0) = 0;
* // fibonacci(1) = 1.
*
* // Value to compute fibonacci function for.
* // It is replaced with the answer when computed.
* private volatile int number;
*
* public Fib(int n) { number = n; }
*
* public int getAnswer() {
* if (!isDone()) throw new Error("Not yet computed");
* return number;
* }
*
* public void run() {
* int n = number;
* if (n > 1) {
* Fib f1 = new Fib(n - 1);
* Fib f2 = new Fib(n - 2);
*
* coInvoke(f1, f2); // run these in parallel
*
* // we know f1 and f2 are computed, so just directly access numbers
* number = f1.number + f2.number;
* }
* }
*
* public static void main(String[] args) { // sample driver
* try {
* int groupSize = 2; // 2 worker threads
* int num = 35; // compute fib(35)
* FJTaskRunnerGroup group = new FJTaskRunnerGroup(groupSize);
* Fib f = new Fib(num);
* group.invoke(f);
* int result = f.getAnswer();
* System.out.println(" Answer: " + result);
* }
* catch (InterruptedException ex) {
* System.out.println("Interrupted");
* }
* }
* }
* </pre>
*
* @exception ClassCastException if caller thread is not
* running in a FJTaskRunner thread.
**/
public static void coInvoke(FJTask task1, FJTask task2) {
getFJTaskRunner().coInvoke(task1, task2);
}
/**
* Fork all tasks in array, and await their completion.
* Behaviorally equivalent to:
* <pre>
* for (int i = 0; i < tasks.length; ++i) tasks[i].fork();
* for (int i = 0; i < tasks.length; ++i) tasks[i].join();
* </pre>
**/
public static void coInvoke(FJTask[] tasks) {
getFJTaskRunner().coInvoke(tasks);
}
/**
* A FJTask that holds a Runnable r, and calls r.run when executed.
* The class is a simple utilty to allow arbitrary Runnables
* to be used as FJTasks.
**/
public static class Wrap extends FJTask {
protected final Runnable runnable;
public Wrap(Runnable r) { runnable = r; }
public void run() { runnable.run(); }
}
/**
* A <code>new Seq</code>, when executed,
* invokes each task provided in the constructor, in order.
* The class is a simple utility
* that makes it easier to create composite FJTasks.
**/
public static class Seq extends FJTask {
protected final FJTask[] tasks;
/**
* Construct a Seq that, when executed, will process each of the
* tasks in the tasks array in order
**/
public Seq(FJTask[] tasks) {
this.tasks = tasks;
}
/**
* Two-task constructor, for compatibility with previous release.
**/
public Seq(FJTask task1, FJTask task2) {
this.tasks = new FJTask[] { task1, task2 };
}
public void run() {
for (int i = 0; i < tasks.length; ++i) FJTask.invoke(tasks[i]);
}
}
/**
* Construct and return a FJTask object that, when executed, will
* invoke the tasks in the tasks array in array order
**/
public static FJTask seq(FJTask[] tasks) {
return new Seq(tasks);
}
/**
* A <code>new Par</code>, when executed,
* runs the tasks provided in the constructor in parallel using
* coInvoke(tasks).
* The class is a simple utility
* that makes it easier to create composite FJTasks.
**/
public static class Par extends FJTask {
protected final FJTask[] tasks;
/**
* Construct a Seq that, when executed, will process each of the
* tasks in the tasks array in parallel
**/
public Par(FJTask[] tasks) {
this.tasks = tasks;
}
/**
* Two-task constructor, for compatibility with previous release.
**/
public Par(FJTask task1, FJTask task2) {
this.tasks = new FJTask[] { task1, task2 };
}
public void run() {
FJTask.coInvoke(tasks);
}
}
/**
* Construct and return a FJTask object that, when executed, will
* invoke the tasks in the tasks array in parallel using coInvoke
**/
public static FJTask par(FJTask[] tasks) {
return new Par(tasks);
}
/**
* A <code>new Seq2(task1, task2)</code>, when executed,
* invokes task1 and then task2, in order.
* The class is a simple utility
* that makes it easier to create composite Tasks.
**/
public static class Seq2 extends FJTask {
protected final FJTask fst;
protected final FJTask snd;
public Seq2(FJTask task1, FJTask task2) {
fst = task1;
snd = task2;
}
public void run() {
FJTask.invoke(fst);
FJTask.invoke(snd);
}
}
/**
* Construct and return a FJTask object that, when executed, will
* invoke task1 and task2, in order
**/
public static FJTask seq(FJTask task1, FJTask task2) {
return new Seq2(task1, task2);
}
/**
* A <code>new Par(task1, task2)</code>, when executed,
* runs task1 and task2 in parallel using coInvoke(task1, task2).
* The class is a simple utility
* that makes it easier to create composite Tasks.
**/
public static class Par2 extends FJTask {
protected final FJTask fst;
protected final FJTask snd;
public Par2(FJTask task1, FJTask task2) {
fst = task1;
snd = task2;
}
public void run() {
FJTask.coInvoke(fst, snd);
}
}
/**
* Construct and return a FJTask object that, when executed, will
* invoke task1 and task2, in parallel
**/
public static FJTask par(FJTask task1, FJTask task2) {
return new Par2(task1, task2);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?