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 &lt; tasks.length; ++i) tasks[i].fork();
   * for (int i = 0; i &lt; 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 + -
显示快捷键?