A Technology Blog About Code Development, Architecture, Operating System, Hardware, Tips and Tutorials for Developers.

Thursday, July 26, 2012

MULTICORE ARCHITECTURE AND SOA

7:09:00 PM Posted by Satish Kumar , , , , , 2 comments

With the success of multi-core architectures, enterprise applications derive benefits by executing the code in parallel. By definition, a multi-core microprocessor is one that combines two or more independent processors into a single package, often a single integrated circuit (IC). This architecture allows software applications to perform thread-level parallelism (chip-level multiprocessing) without including multiple microprocessors in separate physical packages. Now the question arises "why multi-core?" The answer lies in scalability, division of labor, specialization of labor, increased demands for performance and reduced power consumption.

Keeping aside hardware implications, we will look into the software implications of multi-core computing. The emergence of multi-core processor marks a revised thinking from a software perspective too. Applications won't be able to leverage processor enhancements unless software is highly concurrent. Code components which can be run concurrently benefit the most from multi-core architectures and even multiple applications can benefit a lot from multi-core architectures. Then you can run each virtual machine independently of others.

The basic steps in designing parallel applications are:

Partitioning: Decomposing the design into smaller chunks.
Communication: One chunk may require data from another chunk for its smooth execution. This information flow is specified in the communication phase.
Agglomeration: Obtain an algorithm to execute efficiently on a parallel computer. In this phase we combine or agglomerate tasks identified by the partitioning phase to provide a smaller number of useful tasks.
Mapping: Here, we specify where each task is to be executed.
The requirements of a business application do not lend themselves to either grid or parallel environment. 

The three main reasons are:

Order of processing: Business logic must be performed in a particular sequence to ensure the integrity of a business process. Each transaction waits for the previous transaction to be completed before it gets processed. This order of processing is difficult to maintain in a parallel grid environment.
Centrally shared resources: Applications have a centralized resource throughout the application. This creates a bottleneck.
Unpredictable behavior and resource needs: The size and processing requirements of business processes vary through out the day or within a given hour. This makes the division of an application into equal-sized blocks difficult, as well as the allocation of resources.

Multi-core computing in SOA

Service-oriented architectures are gaining popularity due to their inherent flexibility. SOA is an enterprise driven, complex, managed, standards-based and highly customizable architecture to enable maximum flexibility and control. SOA is compositional, meaning new applications are built by plugging services together. However, SOA solutions need higher computational resources due to the dependence upon XML-like or JSON-like languages. To truly benefit from SOA, a parallel processing approach to software design and implementation for SOA is required.

In context of SOA, multi-core computing can be exploited in the following areas


  • Scalability via distributed instances of the same logical service
  • Parallelizing service execution by detecting scope for parallelism
  • Multi-service processes/service orchestration scalability by distributing different services over different threads
  • Separation of different processes in SOA computing – marshalling, schema processing, validation, demarshalling into separate threads for maximizing throughputs for services

Parallel processing.

XML, SOAP, JSON and WSDL are major industry standards used to build SOA applications. However, processing of XML or JSON is computationally demanding and a number of optimization techniques have been developed to address the performance problem, but none of them are quite satisfactory. XML or JSON has turned out to be the major bottleneck for SOA applications. With the emergence of multi-core architectures, concurrent processing of XML or JSON could be one of the solutions to enhance the performance.

SOA can benefit from multi-core architectures, however a set of associated tools and programmer-usable artifacts should be created and made popular so that you do not lay the burden on programmer to create parallel XML or JSON processing code.

Friday, July 20, 2012

MULTITHREADING AND MULTICORE CPU

8:04:00 PM Posted by Satish Kumar , , , 2 comments
After posting the post JAVA CONCURRENCY - PERFORMANCE BOOST, I got a question "how it is going to work in single core CPU and multi core CPU". I was demonstrating the same set of source code for that and I found the program is utilizing only one core of the CPU. I took the help of "htop" tool in Ubuntu to monitor the CPU usage ("htop" is a wrapper around "top" and is having a user friendly UI). My be the purpose of that post was to demonstrate excecuting multiple tasks in parallel and specially the callback approach to save time.


CPU Usage with the program posted in above post:

cpu usage with htop
cpu usage using htop
CPU core no 3 is been utilized with 100% and rest all other cores are hardly used. After lot of google and several coding exercise, I came to the following understaning. I wrote a small program to demonstrate my finding.

Even a single CPU can do "multiple things at the same time" in a loose sense, but they are not truly in parallel. You can start 100 threads to run on a single core and they will get time slices during which each of them can run a few instructions, thus creating the impression that they are all executing at the same time.


The term threads usually covers three abstraction layers:

User threads are threads launched by applications and are mapped N:M to:
Kernel threads, which are threads managed by the operating system, mapped N:M to:
Hardware threads, which are the actual physical resources available.

Java threads are user threads. The 4 cores in your CPU count as hardware threads. Since the mapping is N:M across the layers, you can see that you can have several user threads mapped to a smaller number of hardware threads.

Now, having said this, there are generally two classes of thread activities, each with their own quirks:

I/O threads: these threads spend most of their time waiting on read/write operations from a stream and are blocked in the meantime (they are not scheduled for execution until an event occurs to wake them up). There are light on the CPU and a lot of them can run concurrently even on a single core.

Computational threads: these thread do a lot of number crunching and use the CPU to the maximum. Generally starting more than (2x the number of available cores) such threads is going to degrade performance, because the CPU has a limited number of functional units: ALUs, FPUs, etc.
The second class of threads above lets you really see the benefit or running a multithreaded java program on your quad-core CPU. Here is a simple example of a program that executes squaring of 1.000.000.000 numbers first sequentially and then in parallel using a thread pool with 4 threads:

package org.satish.concurrency;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class ThreadTask implements Runnable {

    private int total = 0;

    public ThreadTask(int total) {
        this.total = total;
    }

    @Override
    public void run() {
        int value = 0;
        for(int i = 0; i < total; i++) {
            System.out.println(value);
            value = i * i;
        }
    }       
}

public class MultiCoreTester {

    public static void main(String[] args) throws InterruptedException {

        int total = 1000000000;

        long start = System.currentTimeMillis();
        long value = 0;
        for(int i = 0; i < total; i++) {
            value = i * i;
        }       
        long stop = System.currentTimeMillis();

        System.out.println((stop - start) + " ms");

        ExecutorService exec = Executors.newFixedThreadPool(4);
        start = System.currentTimeMillis();
        for(int i = 0; i < 4; i++) {
            exec.submit(new ThreadTask(total / 4));
        }
        exec.shutdown();
        exec.awaitTermination(10, TimeUnit.SECONDS);
        stop = System.currentTimeMillis();

        System.out.println((stop - start) + " ms");     
    }
}


cpu usage before staring the program using htop
cpu usage before staring the program using htop
cpu usage after staring the program using htop
cpu usage after staring the program using htop
Before our program starts, all the four cores are hardy used. And once the program get started all the four cores are been used equally.

Thursday, July 19, 2012

GIT - CONTENT MANAGEMENT

6:14:00 PM Posted by Satish Kumar , , , No comments
The following will guide you through a typical Git workflow. You will create a few files, create a local Git repository and commit your file into this repository. Afterwards, you clone the repository and push and pull some changes between the repositories. The comments (marked with #) before the commands explain the specific actions.


Open a command line / shell for the operations.


Create content

The following creates some files with some content that will later be placed under version control.

#Switch to home
cd ~/
# Create a directory
mkdir ~/repo01
# Switch into it
cd repo01
# Create a new directory
mkdir datafiles
# Create a few files
touch test01
touch test02
touch test03
touch datafiles/data.txt
# Put a little text into the first file
ls >test01 

Create repository, add and commit

# Initialize the local Git repository
git init
# Add all (files and directories) to the Git repository
git add .
# Make a commit of your file to the local repository
git commit -m "Initial commit"
# Show the log file
git log 
Every Git repository is stored in the .git folder of the directory in which the Git repository has been created. This directory contains the complete history of the repository. The .git/config file contains the local configuration for the repository.

The following will create a Git repository, add the files to the repository's index and commit the changes.

See differences via diff and commit changes

The git diff command allows the user to see the changes made. In order to test this, make some changes to a file and check what the git diff command shows to you. Then, commit the changes to the repository.

# Make some changes to the file
echo "This is a change" > test01
echo "and this is another change" > test02

# Check the changes via the diff command 
git diff

# Commit the changes, -a will commit changes for modified files
# but will not add automatically new files
git commit -a -m "These are new changes" 

Status, Diff and Commit Log

The following helps you see the current status and the list of commits in your repository.

# Make some changes in the file
echo "This is a new change" > test01
echo "and this is another new change" > test02


# See the current status of your repository 
# (which files are changed / new / deleted)
git status
# Show the differences between the uncommitted files 
# and the last commit in the current branch
git diff

# Add the changes to the index and commit
git add . && git commit -m "More chaanges - typo in the commit message"

# Show the history of commits in the current branch
git log
# This starts a nice graphical view of the changes
gitk --all 

Correction of commit messages - git amend

The git amend command makes it possible to change the last commit message.

In the above example the commit message was incorrect as it contained a typo. The following will correct this via the --amend parameter.

git commit --amend -m "More changes - now correct" 

Delete files

If you delete a file which is under version control git add .will not pick this file up. You need to use the git commit command with the -a flag or the -A flag in the git add command.

# Create a file and put it under version control
touch nonsense.txt
git add . && git commit -m "a new file has been created"
# Remove the file
rm nonsense.txt
# Try standard way of committing -> will not work 
git add . && git commit -m "a new file has been created"
# Now commit with the -a flag
git commit -a -m "File nonsense.txt is now removed"
# Alternatively you could add deleted files to the staging index via
git add -A . 
git commit -m "File nonsense.txt is now removed" 

Tuesday, July 17, 2012

GIT - Setup

8:03:00 PM Posted by Satish Kumar , , , No comments

Git allows you to store global settings in a .gitconfig file. This file is located in the user home directory. As mentioned before Git stores the committer and author in each commit. This and additional information can be stored in the global settings.

The following will configure Git so that a certain user and email address is used, enable color coding and tell Git to ignore certain files.

User Configuration

Configure your user and email for Git via the following command.

# Configure the user which will be used by git
# Of course you should use your name
git config --global user.name "Example Surname"
# Same for the email address
git config --global user.email "your.email@gmail.com"
# Set default so that all changes are always pushed to the repository
git config --global push.default "matching" 

To query your Git settings, execute the following command:

git config --list

Color Highlighting


The following will enable some highlighting for the console.

git config --global color.status auto
git config --global color.branch auto 

Ignore certain files


Git can be configured to ignore certain files and directories. This is configured via the .gitignore file. This file can be in any directory and can contain pattern for files. For example, you can tell Git to ignore the bin directory via the following .gitignore file in the main directory.

bin 


Git also offers the global setting core.excludesfile to specify global excludes.

You can also setup a global .gitignore file valid for all Git repositories.

# Create a ~/.gitignore in your user directory
cd ~/
touch .gitignore

# Exclude bin and .metadata directories
echo "bin" > .gitignore
echo ".metadata" >> .gitignore

# Configure Git to use this file
# as global .gitignore

git config --global core.excludesfile ~/.gitignore 


Tracking empty directories with .gitkeep

Git will ignore empty directories, e.g. do not put them under version control. If you want to track such directories, is it convention to put files called ".gitkeep" in these directories. The file could be called anything; Git assigns no special significance to this name. As the directory now contains a file, Git will include it into its version control mechanism.

GIT - INSTALLATION

7:07:00 PM Posted by Satish Kumar , , , No comments
On Ubuntu you can install the Git command line tool via the following command:

sudo apt-get install git-core 
For other Linux distributions please check your vendor documentation.

A windows version of Git can be found on the msysgit Project site. The URL to this webpage is http://code.google.com/p/msysgit/.

GIT - INTRODUCTION

6:43:00 PM Posted by Satish Kumar , , , No comments
Git is a distributed version control system (DVCS) written in C. A version control system allows the creation of a history for a collection of files and includes the functionality to revert the collection of files to another state. Another state might be a different collection of files or different content in the files.

You may, for example, change the collection of files to a state from 2 days ago or you may switch between states for experimental features and production issues.

The collection of files is usually called "source code". In a distributed version control system everyone has a complete copy of the source code (including the complete history of the source code) and can perform version control operations against this local copy. The use of a DVCS does not require a central code repository.

If you make changes to the source code you mark them as relevant for the version control (add them to the index / staging) and then add them to the repository (commit).

Git maintains all versions. Therefore you can revert to any point in your source code history using Git.

Git performs commits to your local repository and you can synchronize your repository with other (remote) repositories. Git allows you to clone repositories, e.g. create an exact copy of a repository including the complete history of the source code. Owners of repositories can synchronize changes via push (transferring changes to a remote repository) or pull (getting changes from a remote repository).

Git supports branching, e.g. you can have different versions of your source code. If you want to develop a new feature, you may open a branch in your source code and make the changes in this branch without affecting the main line of your code.

Git can be used from the command line. You also find graphical tools, for example EGit for the Eclipse IDE.

Git requires that changes are marked explicitly for the next commit. For example, if you make a change in a file and want that this change is relevant for the next commit, you have to add the file to the so-called "staging index" via the git add file command. The staging index will be a complete snapshot of the changes.

New files must always be explicitly added to the index. For files that have already been committed, you can use the -a flag during a commit.

Thursday, July 12, 2012

JAVA CONCURRENCY - PERFORMANCE BOOST

10:27:00 PM Posted by Satish Kumar , , , No comments
Well after my last post about Executor Framework, I was desperate about finding the practical usage of the framework. I googled the whole day and found some of the search applications, where they used this approach to search in parallel. This approach drastically improves the time complexity!! no doubt. But one thing I noticed, after submitting the tasks the execution is waiting for a particular task to be completed in a queue, even if other tasks in the queue are ready with the result. It does not make much difference, where the execution is not performing any task on the result set. But in a large system, where the system performs 'n' number task on the result set, the new approach will end up boosting the time complexity. No more theory, let's get in to the code. First let me demonstrate the approach, that I googled.

So here I will curl multiple web sites and get the response. I have created a Callable implementation, where I am doing a curl to the web site. This is to give a sense how the search applications gather data from different sources.


package org.satish.concurrency;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Callable;

/**
 * This the callable implementation where I am curling the sites and send the
 * response back.
 * 
 * @author Satish Kumar
 * 
 */
public class WebCurlCallable implements Callable<String> {

    private String siteName;

    WebCurlCallable(String siteName) {
        this.siteName = siteName;
    }

    public String call() {
        StringBuffer response = new StringBuffer();
        try {
            URL url = new URL(this.siteName);
            URLConnection urlConnection = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    urlConnection.getInputStream()));
            String inputLine;

            while ((inputLine = in.readLine()) != null)
                response.append(inputLine);
            in.close();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return this.siteName + " :::::: " + response.toString();

    }

    public String getSiteName() {
        return siteName;
    }

    public void setSiteName(String siteName) {
        this.siteName = siteName;
    }
}
WebCurlCallable.java

Now let me post the actual class from where, I will be creating a thread pool of 3 and will be assigning the task to the threads. If you notice, I will be collecting the Future objects in a list and in the next section I will be looping through the list and will be getting the result set from each Future object. Now in the loop, when the execution encounter the "future.get()", it will wait till completion of the associated task, even if other task in the list already finished and be ready with the result set. In my program I am not doing any post processing after getting the result set. But think of a situation, where you need to perform some task on that result sets. In that case it is a loss of CPU time, which could have been used for some processing.

package org.satish.concurrency;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
public class WebCurlTesterInitial{
  
    /*Thread Pool Size*/
    private static final int NO_OF_THREADS = 3;

    /*List of sites to */
    private static final String siteNames[] = { "http://www.google.com",
            "http://www.yahoo.com", "http://www.touringheights.com",
            "http://satish-tech-talks.blogspot.in/", "http://www.facebook.com",
            "http://www.oracle.com", "http://www.amazon.com", "http://www.cnn.com", "http://www.about.com",
            "http://www.ebay.com", "http://www.download.com" };
     
    /** main thread. Alwyas there by default. **/
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        ExecutorService executor = Executors.newFixedThreadPool(NO_OF_THREADS); 
        List<Future<String>> list = new ArrayList<Future<String>>(10);  // provides facility to return results asynchronously
        
        for (int i = 0; i < siteNames.length; i++) {
            Callable<String> worker = new WebCurlCallable(siteNames[i]); // create worker threads
            Future<String> submit = executor.submit(worker); // add runnables to the work queue
            list.add(submit);
        }
   
      //process the results asynchronously when each thread completes its task
      for (Future<String> future : list) {
        try {
            System.out.println(future.get().substring(0, 60));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
           e.printStackTrace();
        }
      }
   
   
      executor.shutdown();
   
      System.out.println("Finished all threads in  : " + (System.currentTimeMillis() - startTime)/100 + " secs");
   }
 
}
WebCurlTesterInitial.java

Output:


http://www.google.com :::::: <!doctype html><html itemscope 
http://www.yahoo.com :::::: <!DOCTYPE html><html lang="en-IN
http://www.touringheights.com :::::: <!DOCTYPE html PUBLIC "
http://satish-tech-talks.blogspot.in/ :::::: <!DOCTYPE html 
http://www.facebook.com :::::: <!DOCTYPE html><html lang="en
http://www.oracle.com :::::: <!DOCTYPE html PUBLIC "-//W3C//
http://www.amazon.com ::::::   <!DOCTYPE html PUBLIC "-//W3C
http://www.cnn.com :::::: <!DOCTYPE HTML><html lang="en-US">
http://www.about.com :::::: <!doctype html>  <!--[if lt IE 7
http://www.ebay.com :::::: <!DOCTYPE html PUBLIC "-//W3C//DT
http://www.download.com :::::: <!DOCTYPE html>   <html lang=
Finished all threads in  : 105 secs


To utilize that time, I took the help of  FutureTaskFutureTask has a protected method which get triggered, once the task has been completed. By default the "done()" does not do anything. So I extended this class and implemented the "done()" method, the way I wanted. This worked as a callback method for me.


package org.satish.concurrency;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * I picked this implementation, because I what to write call back for each
 * task. FutreTask class has a method done(), which get fired once the task is
 * completed
 * 
 * @author Satish
 * 
 */
public class WebCurlFutureTax extends FutureTask<String> {

    public WebCurlFutureTax(Callable<String> callable) {
        super(callable);
        // TODO Auto-generated constructor stub
    }

    protected void done() {
        /* After completion logic */
        try {
            /*
             * Once the task is completed, get the result and print. User can
             * implement their own logic here i.e. to fire a event or to trigger
             * some other business logic.
             */
            System.out.println(this.get().substring(0, 60));
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

WebCurlFutureTax.java

package org.satish.concurrency;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;

public class WebCurlTester {
    /*Thread Pool Size*/
    private static final int NO_OF_THREADS = 3;

    /*List of sites to */
    private static final String siteNames[] = { "http://www.google.com",
            "http://www.yahoo.com", "http://www.touringheights.com",
            "http://satish-tech-talks.blogspot.in/", "http://www.facebook.com",
            "http://www.oracle.com", "http://www.amazon.com", "http://www.cnn.com", "http://www.about.com",
            "http://www.ebay.com", "http://www.download.com" };

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        ExecutorService executor = Executors.newFixedThreadPool(NO_OF_THREADS); 

        for (int i = 0; i < siteNames.length; i++) {
            Runnable worker = new WebCurlFutureTax(
                    new WebCurlCallable(siteNames[i])); // create worker threads
            executor.submit(worker); // add runnables to the work queue
        }

        // This will make the executor accept no new threads
        // and finish all existing threads in the queue
        executor.shutdown();

        // Wait until all threads have completed
        while (!executor.isTerminated()) {

        }

        System.out.println("Finished all threads in  : " + (System.currentTimeMillis() - startTime)/100 + " secs");
    }
}

WebCurlTester.java

Output:

http://www.google.com :::::: <!doctype html><html itemscope 
http://www.touringheights.com :::::: <!DOCTYPE html PUBLIC "
http://satish-tech-talks.blogspot.in/ :::::: <!DOCTYPE html 
http://www.oracle.com :::::: <!DOCTYPE html PUBLIC "-//W3C//
http://www.yahoo.com :::::: <!DOCTYPE html><html lang="en-IN
http://www.facebook.com :::::: <!DOCTYPE html><html lang="en
http://www.about.com :::::: <!doctype html>  <!--[if lt IE 7
http://www.amazon.com ::::::   <!DOCTYPE html PUBLIC "-//W3C
http://www.cnn.com :::::: <!DOCTYPE HTML><html lang="en-US">
http://www.ebay.com :::::: <!DOCTYPE html PUBLIC "-//W3C//DT
http://www.download.com :::::: <!DOCTYPE html>   <html lang=
Finished all threads in  : 61 secs


Now you can see there is a big difference in time complexity. And till now my callback method does not do much things. Think of a situation where there is a post processing on the resultant. In that case a significant performance can be achieved. This approach can be used for tech solutions, where the CPU time of the distributed servers can be used efficiently. SOA is a great approach to implement concurrent solutions, where the module chunks are distributed among multiple servers. Problem statements can be designed to perform task in a parallel way instead of a serial way.

Wednesday, July 11, 2012

Java 5 Executor Framework

5:01:00 PM Posted by Satish Kumar , , , No comments

A thread pool is a collection of runnables with a work queue. The threads in the pool constantly run and check the work queue for new work. If there is new work to be done they execute this Runnable.

In Java 5, Executor framework was introduced with the java.util.concurrent.Executor interface. This was introduced to fix some of the shortcomings discussed below.

1. The Executor framework is a framework for standardizing invocation, scheduling, execution, and control of asynchronous tasks according to a set of execution policies.



2. Even though the threads are light-weighted than creating a process, creating them utilizes a lot of resources. Also, creating a new thread for each task will consume more stack memory as each thread will have its own stack and also the CPU will spend more time in context switching. Creating a lot many threads with no bounds to the maximum threshold can cause application to run out of heap memory. So, creating a ThreadPool is a better solution as a finite number of threads can be pooled and reused. The runnable or callable tasks will be placed in a queue, and the finite number of threads in the pool will take turns to process the tasks in the queue.

Here is the sample code:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class Sum  implements Runnable {
  
    private static final int NO_OF_THREADS= 3;
  
    int maxNumber;
  
    public Sum(int maxNumber) {
       this.maxNumber = maxNumber;
    }
  
    /** method where the thread execution will start **/
    public void run(){
        int sum = 0;
        for (int i = 0; i = maxNumber; i++) {
           sum += maxNumber;
        } 
         
        System.out.println("Thread " + Thread.currentThread().getName() + " count is " + sum);
    }
     
     
    /** main thread. Always there by default. **/
    public static void main(String[] args) {
       ExecutorService executor = Executors.newFixedThreadPool(NO_OF_THREADS);   // create a pool of 3 threads
       for (int i = 10000; i < 10100; i++) {
          Runnable worker = new Sum(i);               // create worker threads
          executor.execute(worker);                   // add runnables to the work queue 
       }
   
       // This will make the executor accept no new threads
       // and finish all existing threads in the queue
       executor.shutdown();
   
       // Wait until all threads have completed
       while (!executor.isTerminated()) {
 
       }
   
       System.out.println("Finished all threads");
    }
 
}


3. The Runnable interface's void run( ) method has no way of returning any result back to the main thread. The executor framework introduced the Callable interface that returns a value from its call( ) method. This means the asynchronous task will be able to return a value once it is done executing.

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
 
public class Sum  implements Callable<String> {
  
 private static final int NO_OF_THREADS = 3;
  
 int maxNumber;
  
 public Sum(int maxNumber) {
    this.maxNumber = maxNumber;
 }
  
  /** method where the thread execution will start
    *  this can return a value
    */
    public String call(){
        int sum = 0;
        for (int i = 0; i <= maxNumber; i++) {
            sum += maxNumber;
        } 
         
        return Thread.currentThread().getName() + " count is " + sum;
    }
     
     
    /** main thread. Alwyas there by default. **/
    public static void main(String[] args) {
      ExecutorService executor = Executors.newFixedThreadPool(NO_OF_THREADS);                       // create a pool of 3 threads
      List<Future<String>> list = new ArrayList<Future<String>>(10);  // provides facility to return results asynchronously
      
      for (int i = 10000; i < 10100; i++) {
        Callable<String> worker = new Sum(i);                 // create worker threads 
        Future<String> submit = executor.submit(worker);      // add callables to the work queue
        list.add(submit);                                            // provides facility to return results asynchronously
      }
   
      //process the results asynchronously when each thread completes its task
      for (Future<String> future : list) {
        try {
            System.out.println("Thread " + future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
           e.printStackTrace();
        }
      }
   
   
      executor.shutdown();
   
      System.out.println("Finished all threads");
   }
 
}

Output
Thread pool-1-thread-1 count is 100010000
Thread pool-1-thread-2 count is 100030002
Thread pool-1-thread-3 count is 100050006
Thread pool-1-thread-1 count is 100070012
Thread pool-1-thread-1 count is 100090020



4. The various Executor implementations provide different execution policies to be set while executing the tasks. For example, the ThreadPool supports the following policies:

newFixedThreadPool: Creates threads as tasks are submitted, up to the maximum pool size, and then attempts to keep the pool size constant.
newCachedThreadPool: Can add new threads when demand increases, no bounds on the size of the pool.
newSingleThreadExecutor: Single worker thread to process tasks, Guarantees order of execution based on the queue policy (FIFO, LIFO, priority order).
newScheduledThreadPool: Fixed-size, supports delayed and periodic task execution.

5. The ExecutorService provides facilities to shut down an application gracefully, abruptly, or somewhere in-between.

The Executor is based on the producer-consumer design pattern, where threads that submit tasks are producers and the threads that execute tasks are consumers. In the above examples, the main thread is the producer as it loops through and submits tasks to the worker threads. The "Sum" (i.e. a worker thread) is the consumer that executes the tasks submitted by the main (i.e. consumer) thread.

Friday, July 6, 2012

Concurrency: Callable and Future

7:06:00 PM Posted by Satish Kumar , , , No comments

Till Java 1.4, threads could be implemented by either implementing Runnable or extending Thread. This was quite simple, but had a serious limitation - They have a run method that cannot return values. Java 5 introduces the Callable interface, that allows users to return values from a thread. This post describes the Callable and Future interfaces and shows an example of how to use these to interfaces.

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

The call() method is the entry point into a Callable object, and it's return type is the type parameter set in the Callable object. To implement Callable with no return value, use Callable. Also, note that the call() method throws a checked exception, as compared to the run() method in Runnable which does not throw any exception. The Executors class contains utility methods to convert from other common forms to Callable classes. However, Callable cannot be used in place of a Runnable. Callable objects have to be invoked by ExecutorService. The Executor framework provides the Future interface to allow handling the cancellation and returns of a Callable object.
A Future represents the result of an asynchronous computation.

public interface Future {


//Attempts to cancel execution of this task.
boolean cancel(boolean mayInterruptIfRunning);


boolean isCancelled();


boolean isDone();


// Waits if necessary for the computation to complete,
//  and then retrieves its result.
V get() throws InterruptedException, ExecutionException;


// Waits if necessary for at most the given time for the computation
// to complete, and then retrieves its result, if available.
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}

The result can be retrieved using method get() when the computation has completed, blocking if necessary until it is ready. If you would like to use a Future for the sake of cancellation but not provide a usable result, you can declare types of the form Future and return null as a result of the underlying task. The following example demonstrates the use of Callable and future. The first CallableImpl class implements the Callable interface, and returns an integer that is sent to it's constructor. The CallableTester class invokes the CallableImpl through an executor.

package org.satish.concurrency;


import java.util.concurrent.Callable;


public class CallableImpl implements Callable {


private String threadName;


CallableImpl(String i) {
threadName = i;


ExecutorService executor = new ScheduledThreadPoolExecutor(5);

Future future = null;
Callable callable;
for (int i = 0; i < 10000; i++) {
callable = new CallableImpl("Thread - " + i);
future = executor.submit(callable);
}


try {
System.out.println("Future value: " + future.get());
} catch (Exception e) {

e.printStackTrace();

}
}
}


CallableTester.java

LOG


Thread : Thread - 0 :: Looping Job No : 0
Thread : Thread - 1 :: Looping Job No : 0
Thread : Thread - 1 :: Looping Job No : 1
Thread : Thread - 1 :: Looping Job No : 2
Thread : Thread - 1 :: Looping Job No : 3
Thread : Thread - 1 :: Looping Job No : 4
Thread : Thread - 1 :: Looping Job No : 5
Thread : Thread - 1 :: Looping Job No : 6
Thread : Thread - 1 :: Looping Job No : 7
Thread : Thread - 1 :: Looping Job No : 8
Thread : Thread - 1 :: Looping Job No : 9
Thread : Thread - 0 :: Looping Job No : 1
Thread : Thread - 0 :: Looping Job No : 2
Thread : Thread - 0 :: Looping Job No : 3
Thread : Thread - 0 :: Looping Job No : 4
Thread : Thread - 0 :: Looping Job No : 5
Thread : Thread - 0 :: Looping Job No : 6
Thread : Thread - 0 :: Looping Job No : 7
Thread : Thread - 0 :: Looping Job No : 8
Thread : Thread - 0 :: Looping Job No : 9
Thread : Thread - 6 :: Looping Job No : 0
Thread : Thread - 6 :: Looping Job No : 1
Thread : Thread - 6 :: Looping Job No : 2
Thread : Thread - 6 :: Looping Job No : 3
Thread : Thread - 6 :: Looping Job No : 4
Thread : Thread - 6 :: Looping Job No : 5
Thread : Thread - 6 :: Looping Job No : 6
Thread : Thread - 6 :: Looping Job No : 7
Thread : Thread - 6 :: Looping Job No : 8
Thread : Thread - 6 :: Looping Job No : 9
Thread : Thread - 2 :: Looping Job No : 0
Thread : Thread - 2 :: Looping Job No : 1
Thread : Thread - 2 :: Looping Job No : 2
Thread : Thread - 2 :: Looping Job No : 3
Thread : Thread - 2 :: Looping Job No : 4
Thread : Thread - 2 :: Looping Job No : 5
Thread : Thread - 2 :: Looping Job No : 6
Thread : Thread - 2 :: Looping Job No : 7
Thread : Thread - 2 :: Looping Job No : 8
Thread : Thread - 2 :: Looping Job No : 9
Thread : Thread - 7 :: Looping Job No : 0
Thread : Thread - 7 :: Looping Job No : 1
Thread : Thread - 7 :: Looping Job No : 2
Thread : Thread - 7 :: Looping Job No : 3
Thread : Thread - 7 :: Looping Job No : 4
Thread : Thread - 7 :: Looping Job No : 5
Thread : Thread - 7 :: Looping Job No : 6
Thread : Thread - 7 :: Looping Job No : 7
Thread : Thread - 7 :: Looping Job No : 8
Thread : Thread - 7 :: Looping Job No : 9
Thread : Thread - 5 :: Looping Job No : 0
Thread : Thread - 4 :: Looping Job No : 0
Thread : Thread - 4 :: Looping Job No : 1
Thread : Thread - 4 :: Looping Job No : 2
Thread : Thread - 4 :: Looping Job No : 3
Thread : Thread - 4 :: Looping Job No : 4
Thread : Thread - 4 :: Looping Job No : 5
Thread : Thread - 4 :: Looping Job No : 6
Thread : Thread - 4 :: Looping Job No : 7
Thread : Thread - 4 :: Looping Job No : 8
Thread : Thread - 4 :: Looping Job No : 9
Thread : Thread - 5 :: Looping Job No : 1
Thread : Thread - 5 :: Looping Job No : 2
Thread : Thread - 5 :: Looping Job No : 3
Thread : Thread - 5 :: Looping Job No : 4
Thread : Thread - 5 :: Looping Job No : 5
Thread : Thread - 5 :: Looping Job No : 6
Thread : Thread - 5 :: Looping Job No : 7
Thread : Thread - 5 :: Looping Job No : 8
Thread : Thread - 5 :: Looping Job No : 9
Thread : Thread - 3 :: Looping Job No : 0
Thread : Thread - 9 :: Looping Job No : 0
Thread : Thread - 9 :: Looping Job No : 1
Thread : Thread - 9 :: Looping Job No : 2
Thread : Thread - 9 :: Looping Job No : 3
Thread : Thread - 9 :: Looping Job No : 4
Thread : Thread - 9 :: Looping Job No : 5
Thread : Thread - 9 :: Looping Job No : 6
Thread : Thread - 9 :: Looping Job No : 7
Thread : Thread - 8 :: Looping Job No : 0
Thread : Thread - 9 :: Looping Job No : 8
Thread : Thread - 3 :: Looping Job No : 1
Thread : Thread - 9 :: Looping Job No : 9
Thread : Thread - 8 :: Looping Job No : 1
Future value: Thread - 9
Thread : Thread - 3 :: Looping Job No : 2
Thread : Thread - 3 :: Looping Job No : 3
Thread : Thread - 3 :: Looping Job No : 4
Thread : Thread - 3 :: Looping Job No : 5
Thread : Thread - 3 :: Looping Job No : 6
Thread : Thread - 3 :: Looping Job No : 7
Thread : Thread - 3 :: Looping Job No : 8
Thread : Thread - 3 :: Looping Job No : 9
Thread : Thread - 8 :: Looping Job No : 2
Thread : Thread - 8 :: Looping Job No : 3
Thread : Thread - 8 :: Looping Job No : 4
Thread : Thread - 8 :: Looping Job No : 5
Thread : Thread - 8 :: Looping Job No : 6
Thread : Thread - 8 :: Looping Job No : 7
Thread : Thread - 8 :: Looping Job No : 8
Thread : Thread - 8 :: Looping Job No : 9

ExecutorService extends Executor to provides method to manage thread termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks. The method submit extends Executor.execute(java.lang.Runnable) to create and return a Future. Methods invokeAny and invokeAll perform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete. For an overview of Executors, visit Java 5 Executors.