Tuesday, 2 May 2017

Implement Thread pool in Java

What is ThreadPool?
ThreadPool is a pool of threads which reuses a fixed number of threads to execute tasks.

At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available.
ThreadPool implementation internally uses LinkedBlockingQueue for adding and removing tasks.



How ThreadPool works?
We will instantiate ThreadPool, in ThreadPool’s constructor nThreads number of threads are created and started.

/* Create ThreadPool of Size#4. */
ThreadPool pool = newThreadPool(4);
Here 4 threads will be created and started in ThreadPool. Then, threads will enter run() method of PoolWorker class and will call poll() method on queue.

If tasks are available thread will execute task by entering run() method of task else waits for tasks to become available. (As tasks executed always implements Runnable).

public voidrun() {
       Runnable task;
       while(true) {
              synchronized (queue) {
                     while(queue.isEmpty()) {
                           try {
                                  queue.wait();
                           } catch(InterruptedException e) {
                                  System.out.println("An error while queue is
                                  waiting: " + e.getMessage());
                           }
                     }
                     task = queue.poll();
              }

              // If we don't catch RuntimeException, the pool could leak threads
              try {
                     task.run();
              } catch(RuntimeException e) {
                     System.out.println("Thread pool is interrupted: "
                            + e.getMessage());
              }
       }
}

When tasks are added?
When execute() method of ThreadPool is called, it internally calls add() method on queue to add tasks.

      public voidexecute(Task task) {
            synchronized (queue) {
                  queue.add(task);
                  queue.notify();
            }
      }
Once tasks are available all waiting threads are notified that task is available.

In the above code, we used notify() instead of notifyAll(). Because notify() has more desirable performance characteristics than notifyAll(); in particular, notify() causes many fewer context switches, which is important in a server application. But it is important to make sure when using notify() in other situation as there are subtle risks associated with using notify(), and it is only appropriate to use it under certain specific conditions.

How threads in ThreadPool can be stopped?
shutDown() method can be used to stop threads executing in ThreadPool, once shutdown of ThreadPool is initiated, previously submitted tasks are executed, but no new tasks could be accepted.

After thread has executed task
Check whether pool shutDown has been initiated or not, if pool shutDown has been initiated and
queue does not contain any unExecuted task (i.e. queue size is 0) than interrupt() the thread.

public voidrun() {
       Runnable task;
       while(true) {
              …………………………………………………………………
              …………………………………………………………………
              …………………………………………………………………
              …………………………………………………………………
              /*
               * 1) Check whether pool shutDown has been initiated or not,
               * If pool shutDown has been initiated
               * AND
               * 2) queue does not contain any unExecuted task(i.e. queue's size is 0)
               *            than  interrupt() the thread.
               */
              if(this.threadPool.isPoolShutDownInitiated()
                           &&  this.threadPool.queue.size()==0){
                     this.interrupt();
                     /*
                      *  Interrupting basically sends a message to the thread
                      *  indicating it has been interrupted but it doesn't cause
                      *  a thread to stop immediately,
                      *  If sleep is called, thread immediately throws
                      *  InterruptedException
                      */
                     try {
                           Thread.sleep(1);
                     } catch(InterruptedException e) {
                           System.out.println("InterruptedException while calling sleep.");
                     } 
              }
       }
}

Effective use of ThreadPools
Thread pool is a powerful mechanism for structuring multithreaded applications, but it is not without risk. Applications built with thread pools could have all the same concurrency risks as any other multithreaded applications, such as deadlock, resource thrashing, synchronization or concurrency errors, thread leakage and request overload.
Some important points:
1. Do not queue tasks which wait synchronously for other tasks as this can cause a deadlock.
2. If the task requires waiting for a resource such as I/O, specify a maximum wait time and then fail or requeue the task execution. This guarantees that some progress will be made by freeing the thread for another task that might complete successfully.
3. Tune the thread pool size effectively, and understand that having too few threads or too many threads both can cause problems. The optimum size of a thread pool depends on the number of available processors and the nature of the tasks on the work queue.

ThreadPool implemention:
ThreadPool.java
package com.thread;
importjava.util.concurrent.LinkedBlockingQueue;

public class ThreadPool {

      private final int nThreads;
      private final PoolWorker[] threads;
      private final LinkedBlockingQueue<Task> queue;
      private boolean poolShutDownInitiated;

      publicThreadPool(int nThreads) {
            this.nThreads = nThreads;
            this.threads = new PoolWorker[this.nThreads];
            this.queue = newLinkedBlockingQueue<Task>();

            for (int i = 0; i < nThreads; i++) {
                  threads[i] = new PoolWorker(this);
                  threads[i].start();
            }
      }

      public void execute(Task task) {
            synchronized (queue) {
                  queue.add(task);
                  queue.notify();
            }
      }

      public boolean isPoolShutDownInitiated() {
            return poolShutDownInitiated;
      }

      /**
       * Initiates shutdown of ThreadPool, previously submitted tasks
       * are executed, but no new tasks will be accepted.
       */
      public synchronized void shutdown(){
            this.poolShutDownInitiated = true;
            System.out.println("ThreadPool SHUTDOWN initiated.");
      }



      private class PoolWorker extends Thread {
            private ThreadPool threadPool;
            public PoolWorker(ThreadPool threadPool) {
                  this.threadPool = threadPool;
            }

            public voidrun() {
                  Runnable task;
                  while(true) {
                        synchronized (queue) {
                              while (queue.isEmpty()) {
                                    try {
                                          queue.wait();
                                    } catch (InterruptedException e) {
                                          System.out.println("Error while queue is waiting:" + e.getMessage());
                                    }
                              }
                              task = queue.poll();
                        }

                        /* If we don't catch RuntimeException, the pool could leak threads*/
                        try {
                              task.run();
                        } catch (RuntimeException e) {
                              System.out.println("Thread pool is interrupted: " + e.getMessage());
                        }

                        /*
                         * 1) Check whether pool shutDown has been initiated or not,
                         * if pool shutDown has been initiated
                         * AND
                         * 2) queue does not contain any unExecuted task (i.e. queue's size is 0)
                         *          than  interrupt() the thread.
                         */
                        if(this.threadPool.isPoolShutDownInitiated()
                                    &&  this.threadPool.queue.size()==0){
                              this.interrupt();
                              /*
                               *  Interrupting basically sends a message to the thread
                               *  indicating it has been interrupted but it doesn't cause
                               *  a thread to stop immediately,
                               *
                               *  if sleep is called, thread immediately throws
                               *  InterruptedException
                               */
                              try {
                                    Thread.sleep(1);
                              } catch (InterruptedException e) {
                                    System.out.println("InterruptedException while calling sleep.");
                              } 
                        }
                  }
            }
      }
}

Task.java
package com.thread;
public class Task implements Runnable {

    private int num;

    public Task(int n) {
        num = n;
    }

    public void run() {
        System.out.println("Task " + num + " is running.");
    }
}

ThreadPoolTest.java
package com.thread;

/**
 * Test Thread Pool Scheduler
 * @author rajesh.dixit
 */
public class ThreadPoolTest {

    public static void main(String[] args) {
     
      /* Create ThreadPool of Size#4. */
        ThreadPool pool = new ThreadPool(4);

        for (int i = 0; i < 5; i++) {
            Task task = new Task(i);
            pool.execute(task);
        }
    }
}

Garbage Collection Algorithms - memory recycling


The Java virtual machine's heap stores all objects created by a running Java application. Objects are created by the new never freed explicitly by the code. Garbage collection is the process of automatically freeing objects that are no longer referenced by the program.


Why Garbage Collection?

Objects no longer needed by the program are "garbage" and can be thrown away. When an object is no longer referenced can be recycled from heap so that the space is made available new objects.

The garbage collector determines which objects are no longer referenced by the program and make available the heap space occupied by such unreferenced objects.

In the process of freeing unreferenced objects, the garbage collector must run any finalizers of objects being freed.

To freeing unreferenced objects, a garbage collector may also combat heap fragmentation. New objects are allocated, and unreferenced objects are freed such that free portions of heap memory are left in between portions occupied by live objects. New object may allocated by extending the size of the heap even though there is enough total unused space in the existing heap. If there is not enough contiguous free heap space available into which the new object will fit.

On a virtual memory system, the extra paging (or swapping) required to service an ever growing heap can degrade the performance of the executing program. On an embedded system with low memory, fragmentation could cause the virtual machine to "run out of memory" unnecessarily.

Advantages, Garbage collection relieves programmer from the burden of freeing allocated memory. It helps ensure program integrity. Garbage collection is an important part of Java's security strategy.

Disadvantage, The JVM has to keep track of which objects are being referenced by the executing program, and finalize and free unreferenced objects on the fly. This activity will likely require more CPU time than would have been required if the program explicitly freed unnecessary memory. Programmers in a garbage-collected environment have less control over the scheduling of CPU time devoted to freeing objects that are no longer needed.

Garbage Collection Algorithms

Garbage collection algorithm has two basic steps.
It must detect garbage objects.

It must reclaim the heap space used by the garbage objects and make the space available again to the program.

Garbage detection is ordinarily accomplished by defining a set of roots and determining reachability from the roots. If there is some path of references from the roots, an object is reachable (considered "live" else considered garbage because there longer use in program execution).

The root set is dependent JVM implementation, but would always include any object references in the local variables and operand stack, object references (any class variables, strings constant pool of loaded classes).

The constant pool of a loaded class may refer to strings stored on the heap, such as the class name, superclass name, super interface names, field names, field signatures, method names, and method signatures.

Two basic approaches to distinguishing live objects from garbage are reference counting and tracing.

Reference Counting Collectors

Reference counting garbage collectors distinguish live objects from garbage objects by keeping a count for each object on the heap. The count keeps track of the number of references to that object.

Reference counting was an early garbage collection strategy. In this approach, a reference count is maintained for each object on the heap. When an object is first created and a reference to it is assigned to a variable, the object's reference count is set to one. When any other variable is assigned a reference to that object, the object's count is incremented. When a reference to an object goes out of scope or is assigned a new value, the object's count is decremented.

Any object with a reference count of zero can be garbage collected. When an object is garbage collected may lead to subsequent garbage collection if any objects refers garbage collected object.

Advantage, of this approach is that a reference counting collector can run in small chunks of time closely interwoven with the execution of the program. This characteristic makes it particularly suitable for real-time environments where the program can't be interrupted for very long.

Disadvantage, is that reference counting does not detect cycles: two or more objects that refer to one another. Parent object has a reference to a child object that has a reference back to the parent. These objects will never have a reference count of zero even though they may be unreachable by the roots of the executing program.

Reference counting is the overhead of incrementing and decrementing the reference count each time.

Because of the disadvantages inherent in the reference counting approach, this technique is currently out of favor.


Tracing Collectors

Tracing garbage collectors trace out the graph of object references starting with the root nodes. Objects that are encountered during the trace are marked in some way. Marking is generally done by either setting flags in the objects themselves or by setting flags in a separate bitmap. After the trace is complete, unmarked objects are known to be unreachable and can be garbage collected.

The basic tracing algorithm is called "mark and sweep."  In the mark phase, the garbage collector traverses the tree of references and marks each object it encounters. In the sweep phase, unmarked objects are freed.
In the JVM, the sweep phase must include finalization of objects.

Compacting Collectors

Garbage collectors of JVM will likely have a strategy to combat heap fragmentation.

Mark and sweep collectors are commonly uses two strategies compacting and copying.

Both of these approaches move objects on the fly to reduce heap fragmentation. Compacting collectors slide live objects over free memory space toward one end of the heap result to other end of the heap becomes one large contiguous free area. All references to the moved objects are updated to refer to the new location.

Updating references to moved objects is sometimes made simpler by adding a level of indirection to object references. Instead of referring directly to objects on the heap, object references refer to a table of object handles. The object handles refer to the actual objects on the heap. When an object is moved, only the object handle must be updated with the new location. All references to the object in the executing program will still refer to the updated handle, which did not move. While this approach simplifies the job of heap de-fragmentation, it adds a performance overhead to every object access.

Copying Collectors

Copying garbage collectors move all live objects to a new area. As the objects are moved to the new area, they are placed side by side, thus eliminating any free space that may have separated them in the old area.

Advantage, of this approach is that objects can be copied as they are discovered by the traversal from the root nodes. There are no separate mark and sweep phases. Objects are copied to the new area on the fly, and forwarding pointers are left in their old locations. The forwarding pointers allow the garbage collector to detect references to objects that have already been moved. The garbage collector can then assign the value of the forwarding pointer to the references so they point to the object's new location.

A common copying collector algorithm is called "stop and copy."

In this scheme, the heap is divided into two regions. Only one of the two regions is used at any time. Objects are allocated from one of the regions until all the space in that region has been exhausted. At that point program execution is stopped and the heap is traversed. Live objects are copied to the other region as they are encountered by the traversal. When the stop and copy procedure is finished, program execution resumes. Memory will be allocated from the new heap region until it too runs out of space. At that point the program will once again be stopped. The heap will be traversed and live objects will be copied back to the original region. The cost associated with this approach is that twice as much memory is needed for a given amount of heap space because only half of the available memory is used at any time.






Disadvantage, of simple stop and copy collectors is that all live objects must be copied at every collection.


Generational Collectors

This facet of copying algorithms can be improved:
  1. Most objects created by most programs have very short lives.
  2. Most programs create some objects that have very long lifetimes. A major source of inefficiency in simple copying collectors is that they spend much of their time copying the same long-lived objects again and again.
Generational collectors address this inefficiency by grouping objects by age and garbage collecting younger objects more often than older objects. In this approach, the heap is divided into two or more sub-heaps, each of which serves one "generation" of objects. The youngest generation is garbage collected most often. As most objects are short-lived, only a small percentage of young objects are likely to survive their first collection. Once an object has survived a few garbage collections as a member of the youngest generation, the object is promoted to the next generation: it is moved to another sub-heap. Each progressively older generation is garbage collected less often than the next younger generation. As objects "mature" (survive multiple garbage collections) in their current generation, they are moved to the next older generation.

The generational collection technique can be applied to mark and sweep algorithms as well as copying algorithms. In either case, dividing the heap into generations of objects can help improve the efficiency of the basic underlying garbage collection algorithm.


Adaptive Collectors

An adaptive algorithm the current situation on the heap and adjusts its garbage collection technique accordingly. It may tweak the parameters of a single garbage collection algorithm as the program runs. Because every garbage collection algorithms work better in some situations, while others work better in other situations. It may switch from one algorithm to another on the fly. Or it may divide the heap into sub-heaps and use different algorithms on different sub-heaps simultaneously.


With an adaptive approach, designers of JVM implementations can choose garbage collection technique and can use algorithms for which it is best suited.

Monday, 1 May 2017

Return statements should not occur in finally blocks


Prevents the RuntimeException from being propagated.

Returning from a finally block suppresses the propagation of any unhandled Throwable which was thrown in the try or catch block.

public static void main(String[] args) {
  try {
    doSomethingWhichThrowsException();
    System.out.println("OK");
  } catch (RuntimeException e) {
    System.out.println("ERROR");
  }                                                      
}

public static void doSomethingWhichThrowsException() {
  try {
    throw new RuntimeException();
  } finally {
    /* ... */
    return;   // Non-Compliant - prevents the RuntimeException from being propagated
  }
}


Key Points about synchronized keyword in java

What is Synchronized keyword?
Synchronized keyword is used to provide mutual exclusive access of a shared resource with multiple threads.

Synchronization guarantees that, no two threads can execute a synchronized method which requires same lock simultaneously or concurrently.

How it works?
Whenever a thread enters into synchronized method or block it acquires a lock and whenever it leaves synchronized method or block it releases the lock.

Lock is released even if thread leaves synchronized method after completion or due to any Error or Exception.

Object or Class level locking?
Thread acquires an object level lock when it enters into an instance synchronized method and acquires a class level lock when it enters into static synchronized method.

synchronized keyword is re-entrant in nature
It means if a synchronized method calls another synchronized method which requires same lock then current thread which is holding lock can enter into that method without acquiring lock.

NullPointerException
synchronization will throw NullPointerException if object used synchronized block is null.synchronized(instance) will throws java.lang.NullPointerException if instance is null.

synchronized block is better than synchronized method
synchronized block is better than synchronized method in Java because by using synchronized block, it lock only critical section of code and avoid locking whole method which can possibly degrade performance.

It’s possible that both static synchronized and non-static synchronized method can run simultaneously or concurrently because they lock on different object.

volatile keyword usage – To avoid the memory consistency error
From java 5 after change in Java memory model reads and writes are atomic for all variables declared using volatile keyword (including long and double variables) and simple atomic variable access is more efficient instead of accessing these variables via synchronized java code. But it requires more care and attention from the programmer to avoid memory consistency errors.

synchronized keyword with constructor
According to the Java language specification we cannot use Java synchronized keyword with constructor it’s illegal and result in compilation error. So you cannot synchronized constructor which seems logical because other threads cannot see the object being created until the thread creating it has finished it.

Reentrant lock
Java.util.concurrent.locks extends capability provided by synchronized keyword for writing more sophisticated programs since they offer more capabilities e.g. Reentrancy and interruptible locks.

synchronized keyword also synchronizes memory.
In fact synchronized synchronizes the whole of thread memory with main memory.

Important method related to synchronization in are wait (), notify() and notifyAll() which is defined in Object class always call in synchronized block or method.

Do not synchronize non-final field on synchronized block
Because reference of non-final field may change any time and then different thread might synchronizing on different objects i.e. no synchronization at all.


private String lock = new String("lock"); // non-final.
synchronized(lock){
    System.out.println("locking on :"  + lock);
}

synchronized code may get warning "Synchronization on non-final field"  in IDE like Netbeans and InteliJ.

Do not String object as lock in java synchronized block
It is not recommended to use String object as lock in java synchronized block because string is immutable object and literal string and interned string gets stored in String pool.

So by any chance if any other part of code or any third party library used same String as there lock then they both will be locked on same object despite being completely unrelated which could result in unexpected behavior and bad performance.
Instead of String object it’s advised to use new Object () for Synchronization in Java on synchronized block.


private static final String LOCK = "lock";   //not recommended
private static final Object OBJ_LOCK = new Object(); //better
public void process() {
   synchronized(LOCK) {
    ........
   }
}

Calendar and SimpleDateFormat
From Java library Calendar and SimpleDateFormat classes are not thread-safe , requires external synchronization in Java to be used in multi-threaded environment.

OSI and TCP/IP model





Layer 1: Physical Layer
The physical layer defines the electrical and physical specifications of the data connection. It defines the relationship between a device and a physical transmission medium (e.g., a copper or fiber optical cable, radio frequency).

This includes the layout of pins, voltages, line impedance, cable specifications, signal timing and similar characteristics for connected devices and frequency (5 GHz or 2.4 GHz etc.) for wireless devices.
It is responsible for transmission and reception of unstructured raw data in a physical medium. It may define transmission mode as simplex, half duplex, and full duplex. It defines the network topology as bus, mesh, or ring being some of the most common.

The physical layer of Parallel SCSI operates in this layer, as do the physical layers of Ethernet and other local-area networks, such as token ring, FDDI, ITU-T G.hn, and IEEE 802.11 (Wi-Fi), as well as personal area networks such as Bluetooth and IEEE 802.15.4.

The physical layer is the layer of low-level networking equipment, such as some hubs, cabling, and repeaters. The physical layer is never concerned with protocols or other such higher-layer items. Examples of hardware in this layer are network adapters, repeaters, network hubs, modems, and fiber media converters.

Layer 2: Data Link Layer
The data link layer provides node-to-node data transfer—a link between two directly connected nodes. It detects and possibly corrects errors that may occur in the physical layer. It defines the protocol to establish and terminate a connection between two physically connected devices. It also defines the protocol for flow control between them.

IEEE 802 divides the data link layer into two sublayers:

Media access control (MAC) layer – responsible for controlling how devices in a network gain access to a medium and permission to transmit data.
Logical link control (LLC) layer – responsible for identifying network layer protocols and then encapsulating them and controls error checking and frame synchronization.
The MAC and LLC layers of IEEE 802 networks such as 802.3 Ethernet, 802.11 Wi-Fi, and 802.15.4 ZigBee operate at the data link layer.

The Point-to-Point Protocol (PPP) is a data link layer protocol that can operate over several different physical layers, such as synchronous and asynchronous serial lines.

The ITU-T G.hn standard, which provides high-speed local area networking over existing wires (power lines, phone lines and coaxial cables), includes a complete data link layer that provides both error correction and flow control by means of a selective-repeat sliding-window protocol.

Layer 3: Network Layer
The network layer provides the functional and procedural means of transferring variable length data sequences (called datagrams) from one node to another connected to the same "network". A network is a medium to which many nodes can be connected, on which every node has an address and which permits nodes connected to it to transfer messages to other nodes connected to it by merely providing the content of a message and the address of the destination node and letting the network find the way to deliver the message to the destination node, possibly routing it through intermediate nodes. If the message is too large to be transmitted from one node to another on the data link layer between those nodes, the network may implement message delivery by splitting the message into several fragments at one node, sending the fragments independently, and reassembling the fragments at another node. It may, but need not, report delivery errors.

Message delivery at the network layer is not necessarily guaranteed to be reliable; a network layer protocol may provide reliable message delivery, but it need not do so.

A number of layer-management protocols, a function defined in the management annex, ISO 7498/4, belong to the network layer. These include routing protocols, multicast group management, network-layer information and error, and network-layer address assignment. It is the function of the payload that makes these belong to the network layer, not the protocol that carries them.

Layer 5: Session Layer
The session layer controls the dialogues (connections) between computers. It establishes, manages and terminates the connections between the local and remote application. It provides for full-duplex, half-duplex, or simplex operation, and establishes check pointing, adjournment, termination, and restart procedures. The OSI model made this layer responsible for graceful close of sessions, which is a property of the Transmission Control Protocol, and also for session check pointing and recovery, which is not usually used in the Internet Protocol Suite. The session layer is commonly implemented explicitly in application environments that use remote procedure calls.

Layer 6: Presentation Layer
The presentation layer establishes context between application-layer entities, in which the application-layer entities may use different syntax and semantics if the presentation service provides a mapping between them. If a mapping is available, presentation service data units are encapsulated into session protocol data units, and passed down the protocol stack.

This layer provides independence from data representation (e.g., encryption) by translating between application and network formats. The presentation layer transforms data into the form that the application accepts. This layer formats and encrypts data to be sent across a network. It is sometimes called the syntax layer.

The original presentation structure used the Basic Encoding Rules of Abstract Syntax Notation One (ASN.1), with capabilities such as converting an EBCDIC-coded text file to an ASCII-coded file, or serialization of objects and other data structures from and to XML.

Layer 7: Application Layer

The application layer is the OSI layer closest to the end user, which means both the OSI application layer and the user interact directly with the software application. This layer interacts with software applications that implement a communicating component. Such application programs fall outside the scope of the OSI model. Application-layer functions typically include identifying communication partners, determining resource availability, and synchronizing communication. When identifying communication partners, the application layer determines the identity and availability of communication partners for an application with data to transmit. When determining resource availability, the application layer must decide whether sufficient network resources for the requested communication are available.
Related Posts Plugin for WordPress, Blogger...