From Passion to Profession
  • Home
  • Notes
  • Projects
  • Resources
    • Discovery Log
    • Books I Read
    • Blogs I Visit
    • Tools I Use
  • Home
  • Notes
  • Projects
  • Resources
    • Discovery Log
    • Books I Read
    • Blogs I Visit
    • Tools I Use

Java Multithreading Approaches (Java Concurrency - Part 1)

7/7/2013

0 Comments

 
In Java concurrency, there are two low level concurrency implementations in Java to create a thread - extend the Thread class or implement Runnable interface.  These basic approaches neither return value from the thread nor throw exception should anything goes wrong. There's a third approach since Java 1.5 - use Java Concurrency package which supports to receive return values from thread execution.

approach #1: extend Thread class

When you extend the Thread class to create your custom Thread class, you also implement a run() method which will be invoked when the thread gets started. Since you extend Thread class, you won't be able to extend any other class. Therefore, this approach has the least flexibility for coders.
public class MyThread extends Thread{
  // this method is called when a thread starts
  public void run(){
    ...
  }
}

public class ThreadDemo{

  public static void main(String args[]){
    Thread t1 = new MyThread();
    Thread t2 = new MyThread();
    Thread t3 = new MyThread();
    t1.start();
    t2.start();
    t3.start();

  }
}

approach #2: implement Runnable interface

When you implements the Runnable interface to create your own custom thread class, you also need to implement a run() method which will be invoked when your thread gets started. Your custom thread class will be a thread that you instantiate with your Runnable via a constructor. After that, starting a thread is the same, you call upon start() method of the thread to spawn a thread. This approach of implementing the Runnable interface leaves some room for the Thread class to implement other interfaces and extend one other class.
public class MyRunnable implements Runnable{
  // this method is called when a runnable thread starts
  public void run(){
    ...
  }
}

public class ThreadDemo{
  public static void main(String args[]){
    Thread t1 = new Thread(new MyRunnable); // 1
    Thread t2 = new Thread(new MyRunnable);
    Thread t3 = new Thread(new MyRunnable);
    t1.start();    
    t2.start();
    t3.start();

  }
}

[1] A Runnable is passed to Thread's constructor for constructing a Thread using the Runnable approach.

approach #3: java.util.concurrency package - ExecutorService

Since Java 1.5, there's additional way to spawn threads -  java.util.concurrent package. Specifically, ExecutorService. Think of ExecutorService as a thread pool that provides methods to execute threads.

Execute a Runnable

If you have legacy or existing Runnable classes that you'd like them to run in threads, and you have no return values from the threads to process, you 

  1. first decide how many threads (thread pool size) to run concurrently in a given thread pool, then 
  2. consider how many jobs to launch among threads in the pool, then
  3. execute to launch tasks one by one, then
  4. accept no new tasks, then
  5. wait for threads to complete execution.
import java.util.concurrent.*;

public class ThreadDemo{
  public static void main(String args[]){
    int poolSize = Runtime.getRuntime().availableProcessors(); // 1
    int jobCount = 30;                       // 2
    ExecutorService pool = Executors.newFixedThreadPool(poolSize);
    Runnable runnable = new MyRunnable()
    for (int i = 0; i < jobCount; i++) {
      pool.execute(runnable);                // 3
    }
    pool.shutdown();                         // 4
    
    pool.awaitTermination(1, TimeUnit.HOUR); // 5
    // while (!pool.isTerminated()) { }      // 6, alternative to 5
  }
}
[4] Previously submitted tasks are executed, but no new tasks will be accepted further.
[5,6] Blocks until all tasks/threads have completed execution but wait no more than an hour.
Submit a Callable

Using Java Concurrency package approach, if you have no result to return back from the spawned threads, you 'execute a runnable' . If you do, then you want to 'submit a callable'. Each submission of Callable will return a Future. You then invoke get() on each Future to get the result object of returned from Callable's call() method.

Callable interface is similar to runnable interface in that both are designed for classes whoses instances are to be executed by threads. The differences are:

  1. You implement run() method for a Runnable, whereas you implement call() method for a Callable.
  2. The public call() method of Callable returns an object, whereas the public run() method of Runnable does not.
  3. The Callable instances may throw checked exceptions, whereas the Runnable does not.
import java.util.concurrent.*;

public class ThreadDemo{
  public static void main(String args[]){
    int poolSize = Runtime.getRuntime().availableProcessors();
    int jobCount = 30;
    ExecutorService pool = Executors
.newFixedThreadPool(poolSize);   
    Set<Future<Object>> resultSet = new HashSet<Future<Object>>();

    for (int i = 0; i < jobCount; ++i){
      Future<Object> future = pool.submit(new Callable<Object>() { // 1
        public Object call() { // 2
          // do something
          return result;
        }
      });

      resultSet.add(future);
    }

    for (Future<Object> future: resultSet){
      Object result = future.get(5, TimeUnit.SECONDS) // 3
      // do stuff with result
    }

  }
}
[1] submitting a Callable<V> object to the ExecutorService returns a Future<V> object. This V is also what call() method returns.
[2] call() returns a V that is introduced in the genericized form of the declared Callable<V>
[3] get() method of Future will block until the task is completed or until timeout. It is the equivalent of both the join() call and the get value call as get() returns the value calculated by the Callable instance.

what to read next

  • ForkJoinPool Example (Java Concurrency - Part 2)

references

  • Executors Javadoc
  • ExecutorService Javadoc
  • Future Javadoc

0 Comments



Leave a Reply.

    Categories

    All
    Algorithm
    Concurrency
    CQ
    Data Structure
    Design Pattern
    Developer Tool
    Dynamic Programming
    Entrepreneur
    Functional Programming
    IDE
    Java
    JMX
    Marketing
    Marklogic
    Memory
    OSGI
    Performance
    Product
    Product Management
    Security
    Services
    Sling
    Social Media Programming
    Software Development

    Feed Widget

    Archives

    May 2020
    March 2020
    April 2018
    March 2018
    February 2018
    December 2017
    March 2017
    November 2016
    June 2016
    May 2016
    April 2016
    October 2015
    September 2015
    August 2015
    September 2014
    July 2014
    June 2014
    May 2014
    March 2014
    January 2014
    December 2013
    November 2013
    October 2013
    September 2013
    August 2013
    July 2013
    June 2013

    RSS Feed

in loving memory of my mother  and my 4th aunt
Photos used under Creative Commons from net_efekt, schani, visnup, Dan Zen, gadl, bobbigmac, Susana López-Urrutia, jwalsh, Philippe Put, michael pollak, oskay, Creative Tools, Violentz, Kyknoord, mobilyazilar