### WEBINAR:

On-Demand

Building the Right Environment to Support AI, Machine Learning and Deep Learning

**EJB Concurrency Example: Fibonacci**
The example concurrency application uses the Fibonacci numbers, a common mathematical formula where each element in the sequence is the sum of the previous two numbers. You can formulate it as follows (more efficient formulations would not grow exponentially with respect to

n, but this one will suffice for the example):

```
f(n) = 0, if n=0
f(n) = 1, if n=1
f(n) = f(n-1) + f(n-2), if n>1
```

This produces a sequence that looks like this:

```
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 ...
```

Suppose your requirement is to implement an EJB Fibonacci calculator that can compute, in parallel, the Fibonacci results for a set of numbers. You first must implement a task that calculates the Fibonacci result for a given number. Here's one possible implementation of your FibonacciTask:

```
```**public class** FibonacciTask **extends** AbstractTask
{
**private int** n;
**private long** result;
**public** FibonacciTask(**int** n){
**this**.n = n;
}
**public void** run()
{
result = fibonacci(n);
}
**private long** fibonacci(**int** n){
**long** ret = n;
**if** (n > 1)
ret = fibonacci(n-1) + fibonacci(n-2);
**return** ret;
}
**public int** getN(){
**return** n;
}
**public long** getResult()
{
**return** result;
}
}

The run() method simply calls the fibonacci(n) method and stores the result in the class field. The fibonacci(n) method is a recursive implementation of the formula described earlier.

The next step is to implement the calculateFibonacci() method in FibonacciCalculatorEJB. This method will instantiate the appropriate FibonaaciTask(s) and submit them to the EJBTimerConcurrencyManager for execution. To inject the EJBTimerConcurrencyManager into the ConcurrencyManager variable, you can use the EJB3 @EJB annotation as follows:

```
@Stateless
@Remote
```**public class** FibonacciCalculatorEJB **implements** FibonacciCalculator
{
@EJB
**private** ConcurrencyManager concurrencyManager;
...

The calculateFibonacci method takes as argument an array of numbers whose Fibonacci needs to be computed. This example initially schedules the tasks (one for each Fibonacci number) using the blocking scheduling method (executeAndWait with no timeout) that returns only when *all* Fibonacci results are calculated. The elapsed time is printed along with the result:

```
```**public void** calculateFibonacci(**int**[] numbers)
{
ArrayList<Task> tasks = new ArrayList<Task>();
**for** (**int** i = 0; i < numbers. length; i++)
tasks.add(**new** FibonacciTask(numbers[i]));
**long** initialTime = System.*currentTimeMillis*();
concurrencyManager.executeAndWait(tasks);
**long** elapsedTime = System.*currentTimeMillis*() - initialTime;
printFibonacciResults(tasks,elapsedTime);
}

The following is the printFibonacciResults method implementation:

```
```**private void** printFibonacciResults(Collection<Task> tasks, **long** elapsedTime)
{
*logger*.info("** Completed Fibonacci Computations in " + elapsedTime + "ms **");
**for** (Task task : tasks){
FibonacciTask ft = (FibonacciTask) task;
*logger*.info("Fibonacci(" + ft.getN() + ") = " + ft.getResult());
}
}

Calling the calculateFibonacci method with the numbers 1, 7, 20, 31, and 35 produces the following (the elapsed time will vary depending on your hardware configuration):

```
16:42:41,759 INFO [FibonacciCalculatorEJB] ** Completed Fibonacci Computations in 381ms **
16:42:41,759 INFO [FibonacciCalculatorEJB] Fibonacci(1) = 1
16:42:41,759 INFO [FibonacciCalculatorEJB] Fibonacci(7) = 13
16:42:41,759 INFO [FibonacciCalculatorEJB] Fibonacci(20) = 6765
16:42:41,759 INFO [FibonacciCalculatorEJB] Fibonacci(31) = 1346269
16:42:41,759 INFO [FibonacciCalculatorEJB] Fibonacci(35) = 9227465
```

As you can see, parallelizing the tasks using the concurrency framework is relatively straightforward. One factor to consider in this example is the exponential growth of Fibonacci computation time as n increases. You can provide a timeout parameter to the concurrency manager's executeAndWait method to specify the maximum time you wish to wait. The executeAndWait method returns the set of completed tasks at timeout:

```
```**public void** calculateFibonacci(**int** [] numbers, **long** timeout)
{
ArrayList<Task> tasks = **new** ArrayList<Task>();
**for** (**int** i = 0; i < numbers.length; i++)
tasks.add(**new** FibonacciTask(numbers[i]));
**long** initialTime = System.*currentTimeMillis*();
Collection<Task> completedTasks = concurrencyManager.executeAndWait(tasks, timeout);
**long** elapsedTime = System.*currentTimeMillis*() - initialTime;
printFibonacciResults(completedTasks, elapsedTime);
}

Calling the method with the numbers 1, 4, 9, 24, and 40 and a timeout of 300ms produces the following:

```
16:42:42,089 INFO [FibonacciCalculatorEJB] ** Completed Fibonacci Computations in 310ms **
16:42:42,089 INFO [FibonacciCalculatorEJB] Fibonacci(1) = 1
16:42:42,089 INFO [FibonacciCalculatorEJB] Fibonacci(4) = 3
16:42:42,089 INFO [FibonacciCalculatorEJB] Fibonacci(9) = 34
16:42:42,089 INFO [FibonacciCalculatorEJB] Fibonacci(24) = 46368
```

The output indicates that the executeAndWait returned after 310ms (the extra 10ms is due to overhead) without waiting for Fibonacci(40) to complete.

The following section discusses the implementation details of the EJB Timer-based concurrency framework. It covers the implementation of the non-blocking execute method first, and then discusses the blocking style of execution.