1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
import EDU.oswego.cs.dl.util.concurrent.*;
/**
* Callback version of Fibonacci. Computes:
* <pre>
* Computes fibonacci(n) = fibonacci(n-1) + fibonacci(n-2); for n> 1
* fibonacci(0) = 0;
* fibonacci(1) = 1.
* </pre>
**/
public class FibVCB extends FJTask {
// Performance-tuning constant:
static int sequentialThreshold = 1;
public static void main(String[] args) {
try {
int procs;
int num;
try {
procs = Integer.parseInt(args[0]);
num = Integer.parseInt(args[1]);
if (args.length > 2) sequentialThreshold = Integer.parseInt(args[2]);
}
catch (Exception e) {
System.out.println("Usage: java FibVCB <threads> <number> [<sequntialThreshold>]");
return;
}
FJTaskRunnerGroup g = new FJTaskRunnerGroup(procs);
FibVCB f = new FibVCB(num, null);
g.invoke(f);
g.stats();
long result = f.getAnswer();
System.out.println("FibVCB: Size: " + num + " Answer: " + result);
}
catch (InterruptedException ex) {}
}
volatile int number = 0;
final FibVCB parent; // callback target
int callbacksExpected = 0;
volatile int callbacksReceived = 0;
FibVCB(int n, FibVCB p) { number = n; parent = p; }
// Callback method called from subtasks upon completion
synchronized void addResult(int n) {
number += n;
++callbacksReceived;
}
synchronized int getAnswer() {
if (!isDone()) throw new Error("Not yet computed");
return number;
}
public void run() { // same structure as join-based version
int n = number;
if (n <= 1) {
// nothing
}
else if (n <= sequentialThreshold) {
number = seqFib(n);
}
else {
// clear number so subtasks can fill in
number = 0;
// establish number of callbacks expected
callbacksExpected = 2;
new FibVCB(n - 1, this).fork();
new FibVCB(n - 2, this).fork();
// Wait for callbacks from children
while (callbacksReceived < callbacksExpected) yield();
}
// Call back parent
if (parent != null) parent.addResult(number);
}
// Sequential version for arguments less than threshold
static int seqFib(int n) {
if (n <= 1)
return n;
else
return seqFib(n-1) + seqFib(n-2);
}
}
|