Wednesday, April 20, 2016

How to use comparator in Java ??

package : java.util
public interface Comparator<T>
 
A comparison function that imposes a total ordering on some 
collection of objects.They can be passed to a sort method 
(Collections.sort()) | Arrays.sort()) to allow precise control
over the sort order. 
 
It provides multiple sorting sequence i.e. you can sort the
elements based on any data member. For instance it may be 
on rollno, name, age or anything else.  

Can also be used to control the order of certain data structures 
Sorted sets or Sorted maps , or to provide ordering of collections
of objects that do not have a natural ordering.
 
The ordering set by a comparator c on a set of elements S is said
to be consistent with equals id c.compare(s1,s2) == 0 is logically
same as s1.equals(s2) for every s1 , s2 in S.
 
If compare is not consistent with equals for a sorted set or a 
sorted map , the set or map behaves weirdly as the sorted set / map 
violates the contract set for a set or a map.

Method detail :

int compare(T o1 , T o2);

Compares two arguments for order .
-> o1 is less than o2 , returns negative 
-> o1 is equal to o2 , returns 0 
-> o1 is greater than o2 , returns positive.

The above is a signum function like sgn(expression) that returns 
-1 ,0 or 1 based on the sgn(expression) is negative , zero or 
positive.

Implementor should take care of the following : 
1. Ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) 
for all x and y. 
2. Ensure that the relation is transitive: 
((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.
3. Ensure that compare(x, y)==0 implies that 
sgn(compare(x, z))==sgn(compare(y, z)) for all z.

It is generally the case, but not strictly required that
(compare(x, y)==0) == (x.equals(y)).Generally speaking, any 
comparator that violates this condition should clearly indicate 
this fact. The recommended language is "Note: this comparator 
imposes orderings that are inconsistent with equals."

Exercise : 
 
package sample ;
public class City {
 private String name;
 private int number;

 City(String name, int number) {
  this.name = name;
  this.number = number;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public int getNumber() {
  return number;
 }

 public void setNumber(int number) {
  this.number = number;
 }
} 
 
The above is a model class City having two instance variables 
number and Name .
--------------------------------------------------------------
package sample;

import java.util.Comparator;

public class NumberComparator implements Comparator<City>{

 @Override
 public int compare(City o1, City o2) {
  return o1.getNumber() - o2.getNumber();
 }
} 
 
The above is a number comparator which implements the compare 
method and compares the city numbers .
----------------------------------------------------------------
package sample;

import java.util.Comparator;

public class NameComparator implements Comparator<City> {

 @Override
 public int compare(City o1, City o2) {
  return o1.getName().compareTo(o2.getName());
 }
}

The above is a name comparator which uses the Strings' compareTo 
method to compare the City based on the names.
----------------------------------------------------------------
For below class please see comments : 

package sample;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestComparator {

 public static void main(String[] args) {
  List<City> cList = new ArrayList<City>();
  cList.add(new City("Acity", 10));
  cList.add(new City("Zity", 4));
  cList.add(new City("Fcity", -5));
  cList.add(new City("Kcity", 99));
  cList.add(new City("Rcity", 3));
  cList.add(new City("Bcity", 25));
  
  System.out.println("Name Comparator"); 
                // Sorting the list by passing the nameComparator
  Collections.sort(cList, new NameComparator());
  for (City c : cList) {
   System.out
     .println("City : " + c.getNumber() + " ). " + c.getName());
  }

  System.out.println("Number Comparator");                // Sorting the list by passing the numberComparator    
  Collections.sort(cList, new NumberComparator());
  for (City c : cList) {
   System.out
     .println("City : " + c.getNumber() + " ). " + c.getName());
  }
 } 
}
 
Output : -
  
  Name Comparator
  Name : 10 ). Acity
  Name : 25 ). Bcity
  Name : -5 ). Fcity
  Name : 99 ). Kcity
  Name : 3 ). Rcity
  Name : 4 ). Zity
 
  Number Comparator
  Name : -5 ). Fcity
  Name : 3 ). Rcity
  Name : 4 ). Zity
  Name : 10 ). Acity
  Name : 25 ). Bcity
  Name : 99 ). Kcity
 
Note: Sorting of the Arrays class is as the same as the Collections.

Hope you learnt something new today .

Happy Coding

Monday, April 18, 2016

Using The Java ThreadPoolExecutor framework

Hi folks, 

The following exercise helps you understand and implement java's Thread Pool Executor framework. A thread pool manages the pool of worker threads . It contains a queue that keeps the tasks waiting to be executed.

The most common fixed thread pool always has a specified number of threads running; if a thread is somehow terminated while it is still in use, it is automatically replaced with a new thread. Tasks are submitted to the pool via an internal queue, which holds extra tasks whenever there are more active tasks than threads.

Thread pools address two different problems:

1. They usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead.


2.They provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks.

ThreadPoolExecutor ,  an executor service that executes each submitted task using one of possibly several pooled threads, normally configured using Executors factory methods.

Each ThreadPoolExecutor also maintains some basic statistics, such as the number of completed tasks.

However, programmers are urged to use the more convenient Executors factory methods
a).newCachedThreadPool()[unbounded thread pool, with automatic thread reclamation] ,

b).newFixedThreadpool(int) [fixed size thread pool] and

c).newSingleThreadExecutor()[single background thread].


Using A ThreadPool Executor - 

public ThreadPoolExecutor(int corePoolSize,
                  int maximumPoolSize,
                  long keepAliveTime,
                  TimeUnit unit,
                  BlockingQueue<Runnable> workQueue)

-- Creates a new ThreadPoolExecutor with the given initial parameters and default thread factory and rejected execution handler.
 



-> CorePoolSize and MaxPoolSize

 A ThreadPoolExecutor will automatically adjust the pool size according to the bounds set by corePoolSize & maximumPoolSize. When a new task is submitted  and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full. By setting corePoolSize and maximumPoolSize the same, you create a fixed-size thread pool. By setting maximumPoolSize to an essentially unbounded value such as Integer.MAX_VALUE, you allow the pool to accommodate an arbitrary number of concurrent tasks.New threads are created using a ThreadFactory.The defaultThreadFactory creates threads to all be in the same ThreadGroup and with the same NORM_PRIORITY priority and non-daemon status.By supplying a different ThreadFactory, you can alter the thread's name, thread group, priority, daemon status, etc. 

-> Rejected Tasks - 

New tasks submitted  will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated.In either case, the execute method invokes RejectedExecutionHandler.rejectedExecution .

 ->Hook methods:

This class provides protected overridable beforeExecute(java.lang.Thread , java.lang.Runnable) and afterExecute(java.lang.Runnable , java.lang.Throwable) methods that are called before and after execution of each task. These can be used to manipulate the execution environment; for example, reinitializing ThreadLocals, gathering statistics, or adding log entries. Additionally, method terminated() can be overridden to perform any special processing that needs to be done once the Executor has fully terminated. 

-> Queuing:

Any BlockingQueue may be used to transfer and hold submitted tasks.If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.There are three types of blocking queues : SynchronousQueue , LinkedBlockingQueue , ArrayBlockingQueue. Read more about BlockingQuere here. 

-> Keep-alive times:

If the pool currently has more than corePoolSize threads, excess threads will be terminated if they have been idle for than the keepAliveTime. This provides a means of reducing resource consumption when the pool is not being actively used. Using a value of Long.MAX_VALUE, TimeUnit.NANOSECONDS disables idle threads from ever terminating prior to shutdown.

Exercise :   

1. Let's extend the ThreadPoolExecutor by our own class -

package sample.exercise;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class SampleThreadPoolExecutor extends ThreadPoolExecutor {

public SampleThreadPoolExecutor(int corePoolSize, int maxPoolSize,
long keepAliveTime, TimeUnit timeUnit,
BlockingQueue<Runnable> blockingQueue, ThreadFactory threadFactory) {
super(corePoolSize, maxPoolSize, keepAliveTime, timeUnit,
blockingQueue, threadFactory);
}

@Override
protected void beforeExecute(Thread arg0, Runnable arg1) {
                // s.o.p before execute called
super.beforeExecute(arg0, arg1);
}

@Override
protected void afterExecute(Runnable arg0, Throwable arg1) {
                // s.o.p after execute called
super.afterExecute(arg0, arg1);
}
}

---------------------------------------------------------------------------------------------------------------------

2. Let's create a basic TaskClass class that implements run method of the Runnable interface , the object of this class is the actual task going to the blocking queue of the threadPoolExcecutor.

package sample.exercise;

public class TaskClass implements Runnable {

@Override
public void run() {
System.out.println("Write your task here");
}
}

---------------------------------------------------------------------------------------------------------------------

3.  Let's have a main method to run our executor .

package sample.exercise;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

public class InitThreadPool {

private BlockingQueue<Runnable> blockingQueue;
private ThreadFactory threadFactory = Executors.defaultThreadFactory();
private SampleThreadPoolExecutor executor;
private int corePoolSize;
private int maxPoolSize;
private long keepAliveTime;

public InitThreadPool(BlockingQueue<Runnable> blockingQueue)
throws ConfigurationException {
// set the core poolSize this.corePoolSize = ;
// set the maxPoolSize this.maxPoolSize = ;
// set the keep alive time this.keepAliveTime = ;
TimeUnit timeUnit = TimeUnit.NANOSECONDS;
this.blockingQueue = blockingQueue;
this.executor = new SrimsThreadPoolExecutor(corePoolSize, maxPoolSize,
keepAliveTime, timeUnit, blockingQueue, threadFactory);
}

public static void main(String[] args) throws Exception {
InitThreadPool sampleThreadPool = new InitThreadPool(
new LinkedBlockingQueue<Runnable>());
for (int i = 0; i < 100; i++) {
executor.execute(new TaskClass());
}
                executor.shutdown();
                while (!executor.isTerminated()) {
                }
                System.out.println("Finished all threads");
}
}
----------------------------------------------------------------------------------------------------------------------------------

100 tasks of class TaskClass will be sent to the linkedBlocking queue for execution , meaning 100 run methods will be executed by the executor.
 

I hope you learnt something new through this exercise and your understanding of the ThreadPoolExecutor is clear now.
 

Happy Coding.