Sunday, May 26, 2013

Java Concurrency Part 5

This is the fifth part of the tutorial, and this link goes to the previous post java concurrency part 4

Executor Framework

When a program that runs many concurrent tasks, all the code related to the threads has to be implemented, create a thread object per task, execute the thread, obtain its results, and so on. 
This can bring some problems such as manage not efficiently the resources of the computer and affect the performance of the application.
For large applications a better approach is needed and the executor framework can help with this.

The Executor Framework separates the task of thread creation, its execution and management, it encapsulates functionality and it improves the performance using a pool of threads.

The way the executor framework works is really simple, it only requires instances of Runnable or Callable objects and it takes care of the rest.

The java.util.concurrent.Executors is a utility class for create pools, factories and services for the executor framework.

Example:
public class Server {  
    private ThreadPoolExecutor executor;  
             
    public Server() {  
       executor = (ThreadPoolExecutor)Executors.newCachedThreadPool();//Creates the executor object or a thread pool  
    }
    public void executeTask(Task task) {  
       executor.execute(task);//executes a task  
    }
    public void endServer() {  
       executor.shutdown();// This method shuts down the executor  
    }  
}
  
public class Task implements Runnable {  
   private String name;  

   public Task(String name) {      
     this.name = name;  
   }  
   public void run() {  
     System.out.println(Thread.currentThread().getName() + ", created on: " + new Date());  
     try {  
       TimeUnit.SECONDS.sleep((long) (Math.random() * 10));  
     } catch (InterruptedException e) {  
       e.printStackTrace();  
     }  
     System.out.println(Thread.currentThread().getName() + ", finished on: " + new Date());       
   }  
 }  

 ...........  
 Server server = new Server();  
     for (int i = 0; i < 10; i++) {  
       Task task = new Task("Task " + i);  
       server.executeTask(task);  
     }  
     server.endServer();  
 ...........  

In the previous example the Executors class created a java.util.concurrent.ThreadPoolExecutor object, this class is an implementation of java.util.concurrent.ExecutorService interface. Although ThreadPoolExecutor can be created directly using its constructors, it is recommended to use the Executors class.

The ThreadPoolExecutor uses the execute() method to execute a Runnable or Callable. It has other methods as getPoolSize(), getCompleteTaskCount() to get the state of the pool.
The ThreadPoolExecutor has to be terminated explicitly by calling the endServer() method, otherwise it won't end and the program will never finish.

To avoid to overload the application and provoke a poor performance, the Executors class has the method newFixedThreadPool(int nThreads) which creates a fixed-size thread executor.This executor has a maximum number of threads indicated by the parameter nThreads,and as the java api says “At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks”.

Example:
   ......  
   public Server() {      
     executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);  
   }  
   ......  

In the example the executor is created with a maximum of 5 threads at a time, this means if more than 5 tasks are send to execute only 5 will and the remaining will be blocked until there is a free thread to process them.

Tasks that return a value

The executor framework can run tasks that return a value, this is another advantage of using this framework. For this mechanism the java.util.concurrent.Callable interface is used, instead of having a run() it offers a call() method, which returns any type of object that is specified in the generic form:

                   public interface Callable<V> {
                         V call() throws Exception;
                   }

The ExecutorService has the submit() method which accepts objects of type Callable and executes them, this method returns an object of the type java.util.concurrent.Future, the Future interface has methods to obtain the result generated by the Callable object.

Example:
 public class MultiplyCalculator implements Callable<Integer> {  
   private int operator1;  
   private int operator2;  
   public MultiplyCalculator(int operator1, int operator2) {  
     this.operator1 = operator1;  
     this.operator2 = operator2;  
   }  
   public Integer call() throws Exception {  
     return operator1 * operator2;  
   }  
 }  

 ..........  
 ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);//Maximum 2 threads at a time  
  List<Future<Integer>> resultList = new ArrayList<Future<Integer>>();  
  for (int i = 0; i < 10; i++) {  
       MultiplyCalculator calculator = new MultiplyCalculator((int)(Math.random()*10), (int)(Math.random()*10));  
       Future<Integer> result = executor.submit(calculator);  
       resultList.add(result);  
     }  
     while (executor.getCompletedTaskCount() < resultList.size()) {  
         try {  
         Thread.sleep(50);  
       } catch (InterruptedException e) {  
         e.printStackTrace();  
       }  
     }//Waits for the tasks to complete  
     for (int i = 0; i < resultList.size(); i++) {  
       Future<Integer> result = resultList.get(i);  
       try {        
         System.out.println("The result from the task "+i+ " is:" + result.get());  
       } catch (Exception e) {  
         e.printStackTrace();  
       }   
     }  
 ..........

In the previous example, the Callable objects that perform a multiply operation are sent to the executor using the submit() method, the program waits until all the tasks are finished verifying the getCompletedTaskCount() method of the executor, once they are done the results of the operations are obtained with the get() method of the Future object.

 The ExecutorService has the invokeAny(tasks) method which receives a Collection of tasks then it executes them and returns the result of the firs task that finishes without throwing an Exception, tasks that have not completed are cancelled.

An example where this method could be used is for look up services, an application that wants to look up a database connection in different servers, the first task that finds the service available is the one that is going to be used, the other tasks are ignored.

The previous example implemented with the invokeAny() method would look like this:
 .................  
     ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool();  
     List<MultiplyCalculator> taskList = new ArrayList<MultiplyCalculator>();  
     for (int i = 0; i < 10; i++) {  
       MultiplyCalculator calculator = new MultiplyCalculator((int)(Math.random()*10), (int)(Math.random()*10));  
       taskList.add(calculator);  
     }  
     try {  
        Integer result = executor.invokeAny(taskList);  
        System.out.println("The result from the first task in finish is:" + result);  
     } catch (Exception e) {e.printStackTrace();}  
     // Shutdown the Executor  
     executor.shutdown();  
  .............  

The ExecutorService has another mechanism for running multiple tasks and process the result of all tasks, the invokeAll(tasks) method receives a Collection of tasks, executes them and returns a List of Future objects.

Example:
     ExecutorService executor = (ExecutorService) Executors.newCachedThreadPool();  
     List<MultiplyCalculator> taskList = new ArrayList<MultiplyCalculator>();  
     for (int i = 0; i < 10; i++) {  
       MultiplyCalculator calculator = new MultiplyCalculator((int)(Math.random()*10), (int)(Math.random()*10));  
       taskList.add(calculator);  
     }      
     List<Future<Integer>> resultList = null;      
     try {  
        resultList = executor.invokeAll(taskList);         
     } catch (Exception e) {e.printStackTrace();}      
     executor.shutdown();  
     for (int i = 0; i < resultList.size(); i++) {  
       Future<Integer> result = resultList.get(i);  
       try {        
         System.out.println("The result from the task "+i+ " is:" + result.get());  
       } catch (Exception e) {  
         e.printStackTrace();  
       }   
     }  

In the example instead of sending each task to the executor with the submit() method, all the tasks are grouped in a list and send them to execute through the invokeAll() method.

Schedule Tasks

The Executors utility class can create a pool that schedules tasks after a given delay, or executes them periodically. This pool implements the java.util.concurrent.ScheduledExecutorService interface.

Example:
 ScheduledExecutorService executor=
       (ScheduledExecutorService)Executors.newScheduledThreadPool(1);  
 List<Future<Integer>> resultList = new ArrayList<Future<Integer>>();  
 for (int i=0; i<5; i++) {  
      MultiplyCalculator calculator = new MultiplyCalculator((int)(Math.random()*10), (int)(Math.random()*10));  
                Future future<Integer> = executor.schedule(calculator,i+1 , TimeUnit.SECONDS);  
                 resultList.add(future);  
 }  
 executor.shutdown();  
 // Waits for the finalization of the executor  
 try {  
      executor.awaitTermination(1, TimeUnit.DAYS);  
 } catch (InterruptedException e) {  
      e.printStackTrace();  
 }  
 ..............  

In the example a scheduled pool is created with a pool size of 1, then each thread is scheduled using the schedule() method, this method receives as parameters the task to execute, the period of time to wait before the execution and unit of time.
The executor uses the awaitTermination() method which blocks until all tasks have completed or a timeout occurs.

Rejected tasks

If a task is send to the executor between the shutdown() and the end of its execution, the task is rejected. The executor provides a mechanism to manage this, it just requires an instance of an object that implements the java.util.concurrent.RejectedExecutionHandler interface.

Example:

 public class RejectedTaskController implements RejectedExecutionHandler {  
   public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {  
     System.out.println("The task has been rejected");     
   }  
 }  
 ........  
 RejectedTaskController controller = new RejectedTaskController();      
     ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();  
     executor.setRejectedExecutionHandler(controller)  
 ........  

When a task is rejected the rejecedExecution() method of the RejectedExecutionHandler instance is called.

Go to part 6

Sunday, May 19, 2013

Java Concurrency Part 4

This is the fourth part of the tutorial, and this link goes to the previous post java concurrency part 3

Thread Deadlock

Deadlock happen when two threads are blocked waiting for an object's lock that each thread posses. Neither can run until the other gives up its lock, so they will wait forever or blocked indefinitely.

Example
 public class Deadlock extends Thread {  
           Resource a;  
           Resource b;  
           public Deadlock(Resource a, Resource b,String name) {  
                super(name);  
                this.a = a;  
                this.b = b;  
           }  
           public void run(){  
                synchronized(a) {  
                       try {                           
                          Thread.sleep(10000);  
                     } catch (InterruptedException e) {  
                          e.printStackTrace();  
                     }  
                     synchronized(b) {  
                     }  
                     System.out.println("Thread " + this.getName() + " has ended");       
                }  
           }  
      }  
      ..........  
      Resource a = new Resource();  
      Resource b = new Resource();  
      Deadlock d1 = new Deadlock(a, b, "one");  
      Deadlock d2 = new Deadlock(b, a, "two");  
      d1.start();  
      d2.start();  
      ..........  

In the previous example no message is print to console because the threads never reached the System.out.println() sentence, both threads stay forever waiting in the second synchronized() sentence.

What happens is that the first thread “d1” acquires the “a” Resource lock and the second thread “d2” acquires the “b” resource lock, then both threads sleep for 10 seconds, the sleeping time is for giving time to each thread to run and acquire the lock, then after waking up the deadlock situation is set, each thread will try to get the resource the other thread posses, “d1” will try to acquire “b” and “d2” will try to acquire “a”.

One way to avoid the deadlock situation is to use Locks and obtain the lock using tryLock() method

Thread interaction

Threads can communicate to other threads about their status of an event. The Java API provides two ways to enable this communication.
  1. The helper methods (wait(), notify(), notifyAll()) of the Object class.
  2. The java.util.concurrent.locks.Condition interface.
Using these mechanisms a thread can put itself into a state of waiting until some other thread wakes it if there is a reason to come back from the waiting state.

A thread has to call the wait(), notify(), notifyAll() on an object from a synchronized context or an IllegalMonitorStateException will arise. The thread must synchronize the instance of the object in which is calling the helper methods.

Example:
 public class Calculator extends Thread {  
      private Operation op; 
 
      public void run() {  
            synchronize(op) {  
                  op.wait();  
            }  
      }  
}  

There is an overloaded version of wait that waits for an amount of time, so the thread waits until it is notified or the specified time elapsed.

When the wait() method is invoked on an object, the thread executing that code gives up the the object's lock, however when notify() or notifyAll() are invoked on an object the thread doesn't give up the lock, the lock is released until the synchronized code where the notify() or notifyAll() are used completes.

A common example of thread interaction is the consumer-producer, in this type program two threads interact sending messages between them through a “monitor”. The producer thread as its name says generates messages for the consumer, on the other hand the consumer thread waits for the messages
generated by the producer.

Example:
 public class MessageBox {  
      private String message;  
      private boolean empty = true;  
      public synchronized String take() {  
           //Wait until message is available.  
           while(empty){  
                try {  
                     wait();  
                } catch (InterruptedException e) {  
                     e.printStackTrace();  
                }                 
           }  
           empty=true;  
           notifyAll();  
           return message;  
      }  
      public synchronized void put(String message){  
           //Wait until message has been retrieved.  
           while(!empty) {  
                try {  
                     wait();  
                } catch (InterruptedException e) {  
                     e.printStackTrace();  
                }  
           }  
           empty = false;  
           this.message = message;  
           notifyAll();  
      }  
 }  
 public class Producer extends Thread {  
      private MessageBox mb;  
      public Producer(MessageBox mb) {  
           this.mb = mb;  
      }  
      public void run() {  
           String [] messages = {"Hello", "world", "end"};  
           for (String msg:messages) {  
                mb.put(msg);  
           }  
      }       
 }  
 public class Consumer extends Thread {  
      private MessageBox mb;  
      public Consumer(MessageBox mb) {  
           this.mb = mb;  
      }  
      public void run() {  
           String message = "";  
           while (!message.equalsIgnoreCase("end")) {  
                message = mb.take();  
                System.out.print(message + " ");  
           }  
      }  
 }  
 ..............  
 MessageBox mb = new MessageBox();   
 Consumer consumer = new Consumer(mb);  
 Producer producer = new Producer(mb);  
 consumer.start();  
 producer.start();  
 ..............  

In the pevious example the MessageBox class acts as a monitor, if you don't know what a monitor is check this http://en.wikipedia.org/wiki/Monitor_(synchronization), this class makes the consumer to wait if there is no message to read and notifies it when a message arrive. It is the same for the producer, it makes it to wait if producer wants to send a message and the last message set hasn't been read and notifies it when the message has s been read.

So, the MessageBox through its methods wait(), notify(), notifyAll() makes easier the interaction between the consumer and producer threads, it is important to notice that this methods are used with condition loops, this way is safer to use this methods and avoid deadlock situations.

The java.util.concurrent.locks.Condition interface provides similar functionality to the helper methods of the Object class.

Conditions are associated with locks, the conditions allow threads to have control of a lock and check whether a condition is true or not and, if it's false, suspends the thread until another thread wakes them up.

The java API says this about the Condition interface: Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.

All conditions are associated to a lock and to obtain a Condition instance for a particular Lock instance use its newCondition() method.

                        Lock lock = new ReentrantLock();
                        Condition condition = lock.newCondition();

Condition interface has the await(), signal(), signalAll() and its behavior is just the same as the wait(), notify(), notifyAll() of Object class. These methods must be in a block of code that begins with a call to the lock() method of a Lock object and ends with an unlock() method on the same object, or an IllegalMonitorStateException exception will arise.

          lock.lock();//Gets the lock  
               try {  
                   condition.await();             
            } catch (InterruptedException e) {  
                 e.printStackTrace();  
            } finally {  
                 lock.unlock();//releases the lock  
           }  

In order to implement the consumer-producer example with conditions, we only have to change the MessageBox class, the one that acts as monitor, remove the synchronized keywords for a Lock with a Condition, and change the helper methods of the Object class for the ones of the condition.

 public class MessageBox {  
      private String message;  
      private boolean empty = true;  
      private Lock lock = new ReentrantLock();  
      private Condition condition = lock.newCondition();  
      public String take() {  
           //Wait until message is available.  
           lock.lock();  
           while(empty){                 
                try {  
                     condition.await();  
                } catch (InterruptedException e) {  
                     e.printStackTrace();  
                }            
           }  
           empty=true;  
           condition.signalAll();  
           lock.unlock();  
           return message;  
      }  
      public void put(String message){  
           //Wait until message has been retrieved.  
           lock.lock();  
           while(!empty) {  
                try {  
                     condition.await();  
                } catch (InterruptedException e) {  
                     e.printStackTrace();  
                }                 
           }  
           empty = false;  
           this.message = message;  
           condition.signalAll();  
           lock.unlock();  
      }  
 }  

In the example above the await() method of the Condition acts like the wait() of the Object class and signalAll() acts like the notifyAll(), and the behavior should be the same.

Go to part 5

Sunday, May 12, 2013

Java Concurrency Part 3

This is the third part of the tutorial, and this link goes to the previous post java concurrency part 2


A common situation in programs with multiple threads is when two threads have access or share a single resource like a file, database connection, an object. This scenario can provoke error situations or data inconsistency.

To guarantee that only one thread will execute a critical section, prevent data inconsistency and errors, synchronizations mechanisms should be implemented.

 Java provides two basic mechanisms:
  • The keyword synchronized.
  • The java.util.concurrent.locks.Lock interface and its implementations.
Every object in java has a built in lock, that only comes into play when the object has synchronized some code.

If one thread has the lock of an object, no other thread can have the lock until the first thread releases it.
A thread can acquire more than one lock.

Example:

   
      public class Resource {  
           public synchronized void lock() {  
           System.out.println(“Begining, the thread ” + Thread.currentThread().getName() + “has the lock”);  
                try {                           
                     Thread.sleep(10000);  
                } catch (InterruptedException e) {  
                     e.printStackTrace();  
                }  
           System.out.println(“Ending, the thread ” + Thread.currentThread().getName() + “has the lock”);  
           }  
      }  
      public class Concurrent extends Thread {  
           Resource resource;  
           public Concurrent( Resource resource, String name) {  
                super(name);  
                this. resource = resource;  
           }  
           public void run(){  
                resource.lock();  
           }  
      }  
      .....  
      Resource resource = new Resource();  
      Concurrent c1 = new Concurrent(resource, “one”);  
       c1.start();  
      Concurrent c2 = new Concurrent(resource, “two”);  
      c2.start();  
      ......  

In the previous example two thread access concurrently a resource, but one thread has to wait to the other to finish using the resource since the resource is protected using the synchronized keyword, there is no guarantee which thread will acquire the resource first.

The messages in console should appear:

Begining, the thread one has the lock
Ending, the thread one has the lock
Begining, the thread two has the lock
Ending, the thread two has the lock

or

Begining, the thread two has the lock
Ending, the thread two has the lock
Begining, the thread one has the lock
Ending, the thread one has the lock

The messages for each thread appear consecutive and are not mix since each thread doesn't release the lock of the Resource object until it finishes executing the lock() method.

If the synchronized keyword is removed from the declaration of the lock() in the Resource class, the outcome of the program could be any, an example of the output would be:

Begining, the thread two has the lock
Begining, the thread one has the lock
Ending, the thread one has the lock
Ending, the thread two has the lock

The synchronized keyword can be applied to an object's instance to protect access of a block of code instead of a method, it has the same behavior, the thread who access the block of code tries to acquire the lock of the object.

Example:

 public class Resource {  
           public void lock() {  
                 synchronized(this) {  
           System.out.println(“Begining, the thread ” + Thread.currentThread().getName() + “has the lock”);  
                     try {                           
                          Thread.sleep(10000);  
                     } catch (InterruptedException e) {  
                          e.printStackTrace();  
                     }  
           System.out.println(“Ending, the thread ” + Thread.currentThread().getName() + “has the lock”);       
                }  
           }  
      }  
      ........  


The other synchronization mechanism provided by java is the Lock interface and its implementations, according to the java API “Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements. They allow more flexible structuring, may have quite different properties, and may support multiple associated Condition objects”.

Lock interface provides several methods to obtain a lock from an object with different behaviors.

The following example is the same as the one used above with the synchronized keyword.

Example:

 public class Resource {  
           Lock lockObject = new ReentrantLock();  
           public void lock() {  
                lockObject.lock();//Adquires the lock  
           System.out.println(“Begining thread ” + Thread.currentThread().getName() + “has the lock”);  
                try {                           
                     Thread.sleep(10000);  
                } catch (InterruptedException e) {  
                     e.printStackTrace();  
                }  
           System.out.println(“Ending thread ” + Thread.currentThread().getName() + “has the lock”);  
                lockObject.unlock();//Releasing the lock  
           }  
      }  
      .......  


In the example the ReentrantLock implementation of the Lock interface was used, but the API provides more implementations with different behavior each.

ReentrantLock has another constructor which accepts a boolean parameter known as the fair parameter, and if it is false indicates that any thread that is waiting for the lock will receive it, but if it is true
indicates that the thread that has been waiting for the mos time for the lock will receive it.
                              Lock lock = new ReentrantLock(true);//fair set to true 

The lock() method tries to acquire the lock of the lock object, if another thread has the lock of the object, the thread waits until the thread that has the lock releases it.

When a thread finishes using a lock should invoke unlock() method to release the lock so other threads can access the lock.

The Lock interface has the tryLock() method, and it is similar to the lock() methd, but this method doesn't block waiting for a lock as lock() does, it returns a boolean value indicating if the lock was acquire or not, returns true if the lock was free and was acquired by the current thread, and false otherwise.
This method should be used inside an if() condition, if the lock is obtained a block of code is executed.

                                 If (lockObject.tryLock()) {
                                       .........
                                 }




Sunday, May 5, 2013

Java Concurrency Part 2

Here it is the part 2 from my original post: java-concurrency part-1


Thread's priority

All threads have a priority value between 1 and 10. In most cases, the running thread will have the same priority than the highest priority of the threads in the pool.
If some threads have the same priority, it is the scheduler who decides which thread executes.

By default a thread gets its priority from the thread of execution who created it, but it can be changed through the setPriority(int) method, this method can throw an IllegalArgumentException if the value set is not between 1 and 10.

The static yield() method of the Thread class indicates to the JVM that the current thread can leave the CPU and go to the runnable state allowing other threads with the same or higher priority to run. The JVM does not guarantee that this behavior.

Thread sleep

The static sleep(long) method of the Thread class causes the current thread to stop executing for at least the specified sleep duration in milliseconds indicated by the parameter.
When sleeping time ends the JVM assigns CPU time to the sleeping thread, it continues in the next instruction after the sleep() method call.

 Example:

                     public class Calculator extends Thread {
                    public void run() {
                 System.out.println(“Thread running:” + this.getName() + “, started at:” +
                                              Calendar.getInstance().getTimeInMillis());
                               try {
                                   Thread.sleep(5000);
                               } catch (InterruptedException e) {
                                  e.printStackTrace();
                               }
                 System.out.println(“Thread running:” + this.getName() + “, finished at:” +
                                                 Calendar.getInstance().getTimeInMillis());
                    }
               }

The messages in the console should have a time difference of at least of 5 seconds.

Exceptions

The InterruptedException is thrown be some methods related with the java concurrency API, to indicate that the thread has been interrupted.

If you don't know what is an checked or unchecked exception are, then go to this link http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html

Checked exceptions thrown inside the run() method of a Thread Object should be catch and treated, because the run() method in the Runnable interface doesn't declare any throws clause.

Unchecked exceptions thrown inside the run() method of a Thread Object don't require to catch them and must of the time cause the program to exit. For this type of exceptions Java provides a way to catch and treat the unchecked exceptions thrown in a Thread object to avoid the program ending.



 The steps to implement this are:
  1. Create a class that implements Thread.UncaughtExceptionHandler.
  2. Set the exception handler to the Thread Object.


Example
                  public class ExceptionHandler implements UncaughtExceptionHandler {

                       public void uncaughtException(Thread t, Throwable e) {
                            System.out.println("An exception has been captured");
                            e.printStackTrace(System.out);
                            System.out.println("Thread status: " + t.getState());
                       }
                   }


                   public class Calculator implements Thread {
                         public void run() {
                              throw new RuntimeException(“Exception thrown”);
                         }
                   }

                   ..........
                   Calculator calculator = new Calculator();
                   calculator.setUncaughtExceptionHandler(new ExceptionHandler());
                   calculator.start();
                   ..........

The console should print the messages from the exception handler.

Thread class has another method for handle uncaught exceptions, it is the static method setDefaultUncaughtExceptionHandler(), this methods sets an exception handler for all Threads in the application.

Factory of threads

The factory pattern is a creational pattern whose mission is to create objects. This pattern provide some
advantages such as ease to change the way objects are created, limit the creation of resources, and so on.

The interface java.util.concurrent.ThreadFactory provides a way to implement a Thread object factory. It only has the newThread() method and it receives a Runnable object as a parameter and returns a Thread object.

Example

                     public class Factory implements ThreadFactory {
                           private int counter = 1;

                           public Thread newThread(Runnable r) {
                                Thread t=new Thread(r, "Thread: " +counter);
                                counter++;
                                return t;
                           }
                      }

                      public class Calculator implements Runnable {
                           public void run() {
                                .....
                           }
                      }

                      ....
                     Factory factory=new Factory();
                     Calculator calculator = new Calculator ();
                     for (int i=0; i<10; i++){
                          Thread thread=factory.newThread(calculator);
                           thread.start();
                     }
                     .....

At the end of the for loop 10 threads have been created and started.


Go to part 3