Tuesday, December 31, 2013

Java Bytecode or class file

This post, I will be focusing on the content of Java's class file, known as bytecodes.  Java Virtual Machine uses the stream of bytecode from the class file for executing the program. As a Java programmer one doesn't need to bother about internal structure and format of bytecodes at all, but it's worth knowing how it is organized under the hood.  

Reading Bytecodes

Before reading bytecodes, let's generate one first. I am taking a simple HelloWorld example for this. 

public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello, World!");
}
}

Save above class in your editor to compile it (or compile manually through command prompt). Locate the generated class file and open the same in the text editor. Shown in the below screenshot :


Some of the text does look familiar but it doesn't make sense at all. In fact, it doesn't look like bytecode of the HelloWorld.java. It will make more sense if it had numbers( binary/hex). Even if you use the FileReader API of java to read the class file; the result will be the same. You will neither see the stream of bytes nor code mnemonics

Are we missing something ? Yes.
Class file consists of stream of bytecodes. So we need to read the file as an array of the byte as shown in below class.


import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import javax.xml.bind.DatatypeConverter;

/**
 * Utility to read the contents of class file as byte stream
 * 
 * @author Siddheshwar
 * 
 */
public class ReadClassAsByteStream {

 public static byte[] readFileAsByteArray(String fle) throws IOException {
  RandomAccessFile f = new RandomAccessFile(new File(fle), "r");

  try {
   int length = (int) f.length();
   byte[] data = new byte[length];
   f.readFully(data);
   return data;
  } finally {
   f.close();
  }
 }

 // test method
 public static void main(String[] args) throws IOException {
  String file = "D://workspace/JavaSample/src/HelloWorld.class";
  byte[] b = null;

  try {
   b = readFileAsByteArray(file);
   // convert byte array to Hex
   System.out.println(DatatypeConverter.printHexBinary(b));
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

Output:
CAFEBABE00000033001D0A0006000F09001000110800120A001300140700150700160100063C696E69743E010003282956010004436F646501000F4C696E654E756D6265725461626C650100046D61696E010016285B4C6A6176612F6C616E672F537472696E673B295601000A536F7572636546696C6501000F48656C6C6F576F726C642E6A6176610C000700080700170C0018001901000C48656C6C6F20576F726C642107001A0C001B001C01000A48656C6C6F576F726C640100106A6176612F6C616E672F4F626A6563740100106A6176612F6C616E672F53797374656D0100036F75740100154C6A6176612F696F2F5072696E7453747265616D3B0100136A6176612F696F2F5072696E7453747265616D0100077072696E746C6E010015284C6A6176612F6C616E672F537472696E673B2956002100050006000000000002000100070008000100090000001D00010001000000052AB70001B100000001000A000000060001000000010009000B000C00010009000000250002000100000009B200021203B60004B100000001000A0000000A000200000003000800040001000D00000002000E

Bingo !!! Now, this looks like what we were looking for.
In the main method, I have used DatatypeConverter API to convert the byte array into hex format to print the content in more compact format. 

What is Bytecode

Bytecode is a series of instructions for the Java Virtual Machine and it gets stored in the method area (of JVM). Each instruction consists of a one-byte opcode followed by zero or more operands. The opcode indicates the action to be taken by JVM. The number of opcodes is quite small  (<256) and hence one byte is enough to represent opcodes. This helps to keep the size of the class file compact.

Important Observations on Generated Bytecode

  1. Java class file is a binary stream of byte. These bytes are stored sequentially in class file, without any padding between adjacent items. 
  2. The absence of padding ensures that class file is compact and hence can be quickly transferred over the network. 
  3. Items which occupy more than one byte are split into multiple consecutive bytes in big-endian style (higher bytes first ).
  4. Notice that, the first four bytes are "CAFEBABE" -known as the magic number. The magic number makes the non-Java class file easier to identify. If the class file doesn't start with this magic number then it's definitely not a Java class file. 
  5. The second four bytes of the class file contain the minor and major version numbers. 

Mnemonics Representation of Bytecode

Bytecode of HelloWorld program can be even represented as mnemonics in a typical assembly language style. Java provides class file disassember utility named as javap for doing it. javap utility provides multiple options for printing the content of class file. You can also use ASM Eclipse plugin to see disassembled bytecode of a class in Eclipse.

D:\workspace\JavaSample\src>javap -c HelloWorld.class
Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String Hello World!
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

Friday, December 20, 2013

Annotation parser in Java

Java SE 5 introduced Annotation processing API; which further got extended in Java 6 and in Java 7. Through this API, you can find annotations in your code base and then work with them. 

I have discussed the basics of Annotation in the previous post, link. In this post, I will be focusing on processing annotations put in a class file. 



Annotation Processor

This post will be diving deeper to understand how to process Annotations in a class file. If there is no logic/tool to process/parse annotations embedded in source code then annotations will look more like comments. Java provides support API to create these tools through reflection technique
Before finally looking into Annotation processors; let's see one sample annotation and its use. Below is a definition of an Annotation. Note, the meta-annotation put in below Annotation (meta-annotations have been discussed in the previous post). InvocationAnnotation will be used to specify how many times a method needs to run. 

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface InvocationAnnotation {
 int numberOfTimesToInvoke() default 1;
}


Now let's take a class where above annotation, InvocationAnnotation will be used. 


public class AnnotationUsage {
 @InvocationAnnotation(numberOfTimesToInvoke = 3)
 public void method1() {
  System.out.println(" method1 invocation ....3 times..");
 }

 @InvocationAnnotation
 public void method2() {
  System.out.println(" method2 invocation...1 time");
 }
}


Now let's turn to the real business of extracting information from above class and the performing task as expected.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ProcessAnnotationUsage {
 public static void main(String[] args) {
  AnnotationUsage at = new AnnotationUsage();
  Method[] methods = at.getClass().getMethods();

  for (Method m : methods) {

   InvocationAnnotation ia = m
     .getAnnotation(InvocationAnnotation.class);

   if (ia != null) {
    int count = ia.numberOfTimesToInvoke();

    for (int i = 0; i < count; i++) {
     try {
      m.invoke(at, null);
     } catch (IllegalAccessException 
      | IllegalArgumentException
      | InvocationTargetException e) {
      e.printStackTrace();
     }
    }
   }
  }
 }
}

Output :

method1 invocation ....3 times..

 method1 invocation ....3 times..

 method1 invocation ....3 times..

 method2 invocation...1 time


So above annotation processor reads annotation embedded in method through reflection. Then,  finds out how many times the method needs to be invoked and then finally does that using for loop. The output confirms the same. 

Java 5 also introduced an Annotation Processing Tool (APT) called as apt. And in JDK 6, apt was made part of the compiler.

---
do post your comments/questions below !!!

Sunday, October 13, 2013

Java Annotations

An annotation is a metadata about a Java program; it gives information about the program. It has no direct impact on the program but it can be used later for complementing the program. This feature is one of the fundamental change to the language in Java SE5. The syntax of annotation is quite simple; the language just added @ symbol to achieve it. The at sign (@) indicates to the compiler that what follows is an annotation.

     @override
     public String toString(){
           //override method
      }

Annotations are just like other modifiers like public, static, void etc. 

Why Annotations

Let's take an example of ORM tools (like Hibernate) which map plain java classes to database tables. One simple approach which has been followed traditionally is, to provide a separate XML config file for mapping. So once a Java class is written by a developer, he should write a corresponding XML descriptor file. And in the descriptor file, developer will be binding class name to the table name and similarly class attributes to the table columns. The bean class, as well as XML descriptor file, should be in sync.  This is an extra overhead for the system as well as developer. Annotations allow you to get rid of this extra overhead and provide all mapping details in the bean class itself with very little overhead. It can also be used to get rid of writing some repetitive code. 


Java SE5 built-in Annotations

Java SE5 contains three general purpose built-in annotations :
  1. @Override: indicates to the compiler that the method definition needs to be overridden in the subclass. It is not mandatory but if used it can help detect errors at compile time ( in case if you are not overriding the method properly)
  2. @Deprecated: indicates that the marked element is deprecated and should not be used. If you use a  class, method or field with @Deprecated annotation; compiler generates the warning. 
  3. @SuppressWarnings: used to turn off a specific compiler warning. If you use a deprecated method then the compiler usually generates a warning; which could be eliminated by using this annotation. 


Creating Annotations

Annotations are just like regular Interfaces; with only exception that it can take a default value. Annotations get compiled like regular classes, and if you use any annotation, the compiler ensures that the definition of the same is available in your build path. Let's take a look:

   //Developer annotation    
   public @interface Developer{
          String name();   //element
    }
   
   //TimeToRun annotation with default value 
   public @interface TimeToRun{
          int count() default = 1;  //element with default value
    }

I have defined two annotations above. So, quite logically, if you using above annotations; its definition has to be in the build path. 


Using Annotation

Using annotation is quite easy. You would have definitely come across code where built-in annotation like @override would have been used. Now let's see an example where I would be using custom annotations which has been defined above section. 


   public class AnnotationTest {

    @TimeToRun(count= 3)

    public void method1(){

     //invoke this method 3 times

     System.out.println(" method1 invocation ....3 times..");

     }


    @TimeToRun 
    public void method2(){
          //invoke only once which is default value
       System.out.println(" method2 invocation...1 time");
      }
     }

I have used TimeToRun annotation in two methods. Annotations usually contain elements to specify values. In first method, element takes value of 3 and in second method it takes default value (i.e. 1). So providing element value is optional here.
An annotation without any element, is called as marker annotation.


Making Sense out of Annotations 

So far I have created and used Annotations.  So far, it is cool !
But that's NOT end of life !

The real meaning is still missing. This is one of the important aspect; TimeToRun annotation declared in AnnotationTest.java  will be of no use if there is no logic to interpret it. So, we need to write a utility to process annotations and justify their existence. Along with definition of annotation you need a separate tool to parse and understand annotations embedded in source code. This is done through Java's reflection API. I have reserved a separate post to discuss the same in detail (link).

Meta-annotations

So as the title suggests; meta-annotations are annotations which are used for annotating the annotations. Meta-annotations are required for providing scope to annotations. Annotations can be applied on methods, classes, at compile time, during running program etc. So meta-annotation are used for such purposes. Let cover them :

  • @Target – specifies the type of element this annotation can be applied to.
    • ElementType.TYPE- Class, interface (including annotation) or enum declaration
    • ElementType.FIELD- field or property declaration ( including enums )
    • ElementType.METHOD- method level annotation
    • ElementType.PARAMETER- applied to parameter declaration of a method
    • ElementType.CONSTRUCTOR- constructors declaration 
    • ElementType.LOCAL_VARIABLE- local variable declaration
    • ElementType.ANNOTATION_TYPE-indicates that the declared type itself is an annotation type
  • @Retention – specifies how long the annotation information is kept
    • RetentionPolicy.SOURCE—Retained only at the source level and will be descarded by the compiler
    • RetentionPolicy.CLASS—Retained by the compiler at compile time, but will be ignored by the VM
    • RetentionPolicy.RUNTIME—Retained by the VM so they can be read only at run-time reflectively 
  • @Documented – by default annotations are mentioned in java doc, this meta-annotation will make this annotation to be mentioned.
  • @Inherited – Allows subclasses to inherit parent annotation. 
So whenever you use annotation in your program; you should also provide their scope through meta-annotations. 

Saturday, October 5, 2013

Handling Global Variables in Ext JS

Classes don't exist in JavaScript but Ext JS does a fine job in emulating classes as found in object oriented programming languages. This means everything in Ext JS is a class and these classes mostly fall in either of these categories; Model, View, Controller, and Store. So if you could map any new class to either of these category, things fall in place nicely. Now what if something don't fall in either of these ?

What if you need to move common labels and constants to a separate class. If you are writing plain JavaScript then it's quite trivial but NOT so obvious in Ext JS. Let's figure out how to handle labels or common variables in Ext JS.

Singleton Class

Ext JS has support for singleton classes. By definition, singleton can't be instantiated more than once. Global or common variables can be created using a singleton class.

     Ext.define("App.Constants", {
             singleton  : true,  
             
             BASE_URL : "http://localhost:8080/",
             LABLE_HEADER : "geekrai.blogspot",
             TIMEOUT : 6000
     });

Please, note that, singleton property is set to true. That's all we need to do to convert a class into a singleton class. You can test if it's indeed a singleton by creating an instance of above class :

      Ext.create("App.Constants"); //Throws error

Global variables are added in class as key value pair. Save above content in file Constants.js. File can be created at same level as other packages like model, view etc.

Accessing Constants in Application

Above class needs to get loaded in application to successfully access properties mentioned above. As it holds some of the global variables so ideal place will be to load it inside app.js.

     Ext.application({  
           // include model, view, controller etc.

           requires: ['App.Constants']

     });

Now we are good to access variables in any class as App.Constants.<KEY>.
console.log(App.Constants.TIMEOUT);


*** You can also use Ext JS singleton to create utility classes. 

Thursday, September 26, 2013

Accessing view in the controller of Ext JS 4

Controller in Ext JS framework work as a glue between view, model, store (and data). It can listen to different events on the view/UI and handle events. So if you want to manipulate a particular view then the most appropriate place would be the corresponding controller.

Let's take a simple view named as myView as shown below. I have removed other attributes for making it simpler. Things to note here is alias of the view.

 Ext.define('App.view.myView', {
     extend: 'Ext.panel.Panel',
     alias: 'widget.myview',
    //..

 });

Access View in Controller

Controller might access the same UI component time and again. Ideal approach would be to do it only once and then save a reference to avoid subsequent searches. Controllers provide an easy approach for the same. We can define references using selectors and then we can use them in any of the methods in controller. By using refs array we can define as many references as we want.

Each reference should be an object with at least two configurations. First is the ref property, which is the name of our reference, and second is the selector for the reference.  You should be careful to give selector name as the alias without the keyword 'alias'. And ref is used to give a meaningful name for the same. There is no restriction on ref; you can give any name. And after this view will be available through a getter method as shown below :

 Ext.define('App.controller.myController, {
     extend: 'Ext.app.Controller',

       views: ['myView'],  //Not Required

       refs: [
{ref: 'viewz', selector: 'myview'} 
],
        init: function(application) {
          //event listners 
        },
       hideView: function(){
         var vu= this.getViewz();
        vu.hide();
      }
 });
 

This helps in speeding up the process as searching for the UI/view component will be done only once. And you can use it at multiple places without causing any performance issue. 

Friday, August 2, 2013

Git Commands Cheat Sheet

Provide Your Identity to Git
Configure your identity to Git by setting your name and email id. Git uses this to track your changes when you commit. 
$ git config --global user.name "Siddheshwar Rai"
$ git config --global user.email "rai.skumar@gmail.com"

--global is optional and it means Git will always use above details (for all projects inside repository). To use a different name for a specific project, you should run above commands inside project without passing --global

Set Your Editor
Git uses vi or vim editors by default. If you want to use a different editor you need to override the default value.
$ git config --global core.editor emacs

Set Your Diff Tool
Git supports tools like kdiff3, tkdiff, xxdiff, emerge, vimdiff etc.
$ git config --global merge.tool vimdiff

Check Your configured settings 
$ git config --list
$ git config user.name 

Git Help
$ git help <verb>
$ git help config

Initializing a Repository
If you are starting from scratch and want to track your project in Git. Move to your project directory and then initialize Git repository. 
$ cd /d/workspace/MyProject
$ git init

Above command creates .git directory inside your project. This directory will contain all your necessary repository files. As of now it will be an empty directory.

Add Files to Repository
In order to track file/s; you need to add them to the repository as shown below :
$ git add *.java   #add all java files
$ git add Apple.java
$ git add README

Clone an Existing Repository
If you want to contribute to an existing Git project, you need to start by cloning it. The corresponding thing in SVN/CVS is checkout. When you checkout you get all the latest files of the given project.  This means you get all history data along with the latest one. This way you can also restore your server with your local data in case server gets crashed/corrupted. 
$ git clone <url>
$ git clone https://github.com/raiskumar/XImage.git  #clones my project XImage

Above command creates a directory named as XImage, initializes .git directory inside it and takes out all code.
$ git clone https://github.com/raiskumar/XImage.git MyXimage

Names your local copy as MyXimage instead of XImage. Note that above commands we are using HTTP protocol to fetch code. Similarly, you can use the git protocol as well. 

$ git clone git://github.com/raiskumar/XImage.git


Check File Status
You can check which stage your file is through status command. It also tells you which branch you are on.
$ git status
# On branch master (master is default).

If you add a new file to your project and then run status command then that file will be listed under header Untracked Files. This basically means that Git sees a file you didn't have in the previous snapshot(commit). To include it, you need to commit it. 

Tracking New Files
You begin tracking a file by running add command. After running add command on a file if you run status command then Git shows that file as tracked and staged. 
$ git add README
$ git add dir  # Add all files of the directory
$ git status

Now README file will be under Changes to be Committed heading (means its staged). 

Staging Modified Files
Let's change a file that was already tracked and then run status command. Let that file is A.java.
$ git status

A.java appears under Changes not staged for commit - means, the file that is tracked is modified in the working directory but not staged yet. To stage it; you need to run add command. So through this command, you begin tracking new files, stage files and for marking the merge-conflicted file as resolved. So now running add command on A.java will show it under Changes to be committed heading. 

Now suppose you again modify it and then run the status command again. Now, this file will be shown under?
Both Changes to be committed and Changes not staged for commit.

So it is listed as staged as well as unstaged both. This is because Git staged file as it is when you run add command but it underwent changes after that. 

Ignoring Files
There are cases when you don't want to add some of the files. These could be automatically generated files like logs or files which get generated by the system like compiled files. This you can achieve by creating a .gitignore file.

$ cat .gitignore
*.class

#ignore build directory
build/

#Eclipse . files
.classpath
.project
.settings

#target file which has a jar
target/

Viewing Staged and Unstaged Changes
status command tells only which file changed, but doesn't give details. diff command can be used to know more details about staged/unstaged files and exact changes. Diff command tells which line was changed. 
$ git diff   # see what have you changed but not yet staged 
$ git diff --cached  # see what have you staged which will got to next commit
$ git diff --staged  # 1.6.1 and later 


Committing Your Changes
$ git commit   # launches editor for giving comments 
$ git commit -m "message 1"  # inline message
$ git commit -m "comming message" path/to/dir/*  # commit a particular file/files inside a directory

Note: If you don't give directory path; it will commit all staged files.

Successful commit shows which branch you committed, what SHA-1 checksum the commit has, how many files were changed, statistics about line added/removed.

Show committed files / To-be pushed files
$ git diff --stat origin/master

Above command will list down all file names (one in each line) which are committed.

Last line of output tells number of files changed, insertions(+) performed, and deletions(-) performed.

Skipping the Staging Area
Git provides a simple shortcut -a to skip the staging area.
$ git commit -a -m "Added new file"   

Removing Files
To remove a file from Git, you have to remove it from your tracked files (i.e remove it from staging area ) and then commit. The Git rm command does that and also removes the file from your working directory. 
$ git rm Abc.tmp 
$ git commit   # File is permanently gone 

What if you want to remove file from staging area but keep it in working area. That is, keep file on your hard drive but remove it from Git. This is particularly useful if you forgot to add a file in .gitignore file. 
$ git rm --cached readme.txt 
$ git rm log/\*.log  # Remove all log files 

Moving Files
Unlike some other VCS systems Git doesn't track file movement explicitly. If you rename a file in Git , Git doesn't store its history. 
$ git mv README.txt README 

View Commit History 
Unlike some other VCS systems Git doesn't track file movement explicitly. If you rename a file in Git , Git doesn't store its history. 
$ git log  # Prints history in reverse chronological order 
$ git log -p -2  # Shows difference introduced in each commit; -2 to limit count
$ git log -U1 --word-diff # Word diff instead of line diff
$ git log --stat  # Show abbreviated stats of each commit
$ git log --pretty=oneline  # pretty for changing format other than default (short,full, fulller, oneline)
$ git log --pretty=format:"%h %s " --graph  
$ git log  --since=2.weeks

Push Files
$ git push origin master
$ git push -u origin master
git push origin <branch-name>

Pushes change to 'master' branch at 'origin'.

Note: By convention remote repository is referred to as origin and initial local repository/branch as master

Pull Files
$ git pull origin master

Pulls changes locally from the master. It does two things: it does git fetch and git merge as per the setup in your config.

Undo Last Pull
$ git reset --hard

Above command resets to previous state.

GUI History Visualizer
You can visualize commit history using a GUI tool. 
$ git gitk 

Undoing Things
What if you commit to early, forgot to add something or messed up something. Such case you need to commit again.
$ git commit --ammend  #Takes your stagging area and uses it to commit 
$ git commit -m 'Initial commit '
$ git add Forgotten_File.java
$ git commit --ammend

Fix merge conflicts 
$ git mergetool&
Above command opens a GUI tool if you have installed one.

Create a feature branch from master
$ git branch
master

$git branch feature1

So whatever branch you are on, above command will create a copy of that branch and name it as feature1.

$ git branch

feature1
master

$git checkout feature1

Now, you are on feature1 branch

Saturday, July 6, 2013

Executor Framework in Java

Java 5 introduced a new framework to abstract thread management from the rest of the application. These set of API/objects are popularly known as Executors or Executor framework. Managing thread means; controlling its life cycle, its usage, and its scheduling etc. So through Executors, you don't need to explicitly create threads. Thread creation and management will be taken care of by Executors. As a developer, if you are scared of threads; then Bingo; Executors will make your life simpler and cooler!

Executor APIs

Below class diagram shows major classes which are part of Executor Framework. I have removed attributes/operations from class diagram to make it look neater and lighter. I want to stress more on their relationship; you can always look for details through Java doc.  Let's go briefly through important classes : 

Class Diagram

Executors: This is a utility class which acts as a factory for creating different types of executors which are shown in the above class diagram. Using this you can create an instance of Executor, ExecutorService, ScheduledExecutorService, ThreadFactory and Callable classes.

import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

public class ExecutorSample {

 public static void main(String[] args) {

  Runnable task = new Runnable() {
   public void run() {

   }
  };

  Callable<Object> c = Executors.callable(task);

  Executor ex = Executors.newSingleThreadExecutor();

  ExecutorService exs = Executors.newSingleThreadExecutor();

  ScheduledExecutorService sexs = Executors
    .newSingleThreadScheduledExecutor();
 }
}
   
Executor: This interface has a single method (execute) to execute a Runnable task. So it decouples task submission and execution. As shown below, execute method is equivalent to running a thread in the more traditional way by creating an instance of Thread class.

 //Executor ex = Executors.newSingleThreadExecutor();

import java.util.concurrent.Executor;

public class ExecutorSample {

 public static void main(String[] args) {
  Runnable task = new Runnable() {
   public void run() {
    System.out.println("inside task");
   }
  };

  Executor es = new Executor() {
   @Override
   public void execute(Runnable task) {
    (new Thread(task)).start();
    task.run();
   }
  };
  es.execute(task);
 }
}


ExecutorService: It supplements base class (Executor) by adding more methods to control life cycle. It provides a more versatile submit method which can take Runnable as well as Callable task type. Submit method returns a Future object, which can be used to return the value of Callable task and it can also be used to manage the status. ExecutorService could be in either of three states: running, shutting down, and terminated. The shutdown method initiates a graceful shutdown: no new tasks are accepted but previously submitted tasks are allowed to complete (including those that have not yet begun execution). The shutdownNow method initiates an abrupt shutdown: it attempts to cancel outstanding task and doesn't start any task that is queued but not begun.
ExecuterService es = Executors.xx();
while(!es.isShutdown()){
      //task execution
}
Below class shows invokeAll method example:

import java.util.HashSet;
import java.util.List;
import java.util.Set;
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;

/**
 * Demo of invokeAll method; It can any collection of callable tasks.
 * 
 * @author Sid
 * 
 */
public class InvokeAllDemo {
 public static void main(String[] args) {
  ExecutorService executorService = Executors.newSingleThreadExecutor();
  Set<Callable<String>> callables = new HashSet<Callable<String>>();

  callables.add(new Callable<String>() {
   public String call() throws Exception {
    return "Task 1";
   }
  });
  callables.add(new Callable<String>() {
   public String call() throws Exception {
    return "Task 2";
   }
  });

  try {
   List<Future<String>> futures = executorService.invokeAll(callables);
   executorService.shutdown();

   for (Future<String> future : futures) {
    System.out.println("Response = " + future.get());
   }

  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (ExecutionException e) {
   e.printStackTrace();
  }
  executorService.shutdown();
 }
}

Output:
Response = Task 1
Response = Task 2


ScheduledExecutorService: This interface extends further and adds methods related to scheduling. With this, you can run your Runnable/Callable task after a fixed delay. So it can be used to execute a specified task repeatedly at the fixed interval.

Thread Pools

Managing the thread life cycle is expensive so one of the reason behind this framework is to abstract it. In complicated or real-life applications, allocating and deallocating memory to multiple threads become even more complicated (compared to a single thread). So to handle this, Java introduced the concept of thread pools. 

Thread pool consists of worker threads. Tasks are submitted to a thread pool via a queue. Worker threads have a simple life : request new task from a work queue, execute it, and go back to pool for assignment to next task. Executors class provides the factory method to create thread pools. Let's cover them :

Executors.newFixedThreadPool(10): This is one of the most common types of thread pool. This type of pool always has a specified number of threads running. If a thread from the pool is terminated due to some reason then it automatically gets replaced with a new thread. 

Executors.newCachedThreadPool(): Creates an expandable thread pool which reuses previously created threads if available. These pools will improve the performance of the program that creates many short-lived asynchronous tasks. Threads that have been used for 60 seconds are terminated and removed from the cache. Thus if pool remains idle for longer time will not consume any resource.

Executors.newSingleThreadExecutor() : Creates a single-threaded executor. It's a single worker thread to process tasks, and replaces it if it dies due to some reason/error. So using this, tasks will be executed sequentially. So if you have a queue having 10 tasks, then tasks will get executed one after another depending on the order.


Executors.newScheduledThreadPool() : Creates a fixed size thread pool that supports delayed and periodic task execution. 

Executors also provides dedicated classes for creating thread pools specific to your needs if methods provided through Executors are not enough. These classes are ThreadPoolExecutor, ScheduledThreadPoolExecutor  and ForkJoinPool as shown in above class diagram.

--
do post your comments/questions !!!