Java Multithreading concepts


Java is a multi-threaded programming language which means we can develop multi-threaded program using Java. A multi-threaded program contains two or more parts that can run concurrently and each part can handle a different task at the same time making optimal use of the available resources specially when your computer has multiple CPUs.
By definition, multitasking is when multiple processes share common processing resources such as a CPU. Multi-threading extends the idea of multitasking into applications where you can subdivide specific operations within a single application into individual threads. Each of the threads can run in parallel. The OS divides processing time not only among different applications, but also among each thread within an application.

We can manually create threads in the following ways
1) Class extends Thread class

Example::

import java.util.concurrent.TimeUnit;
public class FirstWay{
public static void main(String args[]) {
System.out.println("Main thread start here");
new FirstTask();
Thread t = new FirstTask();
System.out.println("Main thread end here");
}
}

class FirstTask extends Thread{
private static int count = 0;
private int id;

public void run(){
for(int i=10; i>0; i--){
System.out.println("<" + id + ">TickTick" + i);
try{
TimeUnit.MILLISECONDS.sleep(200);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public FirstTask(){
this.id = ++count;
this.start();
}
}

2) Class implements Runnable

Example::

import java.util.concurrent.TimeUnit;
public class ThirdWay{
public static void main(String args[]) {
System.out.println("Main thread start here");
new ThirdTask();
new ThirdTask();

System.out.println("Main thread end here");
}
}
class ThirdTask implements Runnable{
private static int count = 0;
private int id;

public void run(){
for(int i=10; i>0; i--){
System.out.println("<" + id + ">TickTick" + i);
try{
TimeUnit.MILLISECONDS.sleep(200);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public ThirdTask(){
this.id = ++count;
new Thread(this).start();
}
}


3) Using ExecutorService

Running Thread using ExecutorService - Exists since Java 5
ExecutorService will allow you to initiate Thread pool depending on the configuration without we creating threads manually as shown in the above examples.
If the Thread pool consists of 5 threads and we submit 5 tasks to the work queue, all the 5 tasks will be executed concurrently using the 5 threads in the pool.

Important classes/interfaces while using Executor API

Executor(I) - void execute(Runnable r)
ExecutorService(I) - extends Executor interface. Procides life cycle to the executors. It provides init, service and desctruction phases.
init - init allocated required number of Threads and start them if needed. .
Service - Actually submits the task to the threads
Desctruction - Shutsdown the ExecutorService and dont accept anymore tasks

Methods of the ExecutorService
--------------------------------------------


1) <T>Future<T>submit(Callable<T>task); - Task implementing Callable will return a value
2) Future<?>submit(Runnable task); - Task implementing Runnable will not return any value
3) void shutdown(); - ExecutorService will no longer accept new tasks. Already running tasks and       pending tasks will be executed anyway.
4) List<Runnable>shutdownNow(); - Can forcely shutdown the ExecutorService. It stops executing all the actively running tasks and halts executing the pending tasks. Returns all the pending tasks that were yet to be not executed.
5)boolean isShutdown();

It should also contain execute method as it extends Executor interface


Executors (C) - It is a factory class that returns the ExecutorService implementation class
Methods in Executors are as follows
----------------------------------------------
public static ExecutorService newFixedThreadPool(int nThreads); - N number of threads will be initiated
public static ExecutorService newCachedThreadPool(); Threads will be created on demand
public static ExecutorService newSingleThreadExecutor(); - At a time only one task will be executed sequentially from the queue. It does not maintain a Thread pool. It has only one thread.
public static ExecutorService newSingleScheduledThreadExecutor();  - Only one task will be executed at a scheduled time sequentially from the queue. This also does not maintain Thread pool. It has only one thread.

ThreadPoolExecutor class is the impl of ExecutorService. All the above methods return ThreadPoolExecutor class. If we want to write custom ExecutorService implementations, we can extend the ThreadPoolExecutor class and write our own code

Example of newFixedThreadPool

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import common.LoopTaskA;

public class UsingFixedThreadPool {
public static void main(String[] args) {

ExecutorService execService = Executors.newFixedThreadPool(3); // creates fixed thread pool
ExecutorService execService = Executors.newCachedThreadPool(); // create threads on demand
ExecutorService execService = Executors.newSingleThreadExecutor()  // creates only one thread and executes only one task at a time.

execService.execute(new LoopTaskA());
execService.execute(new LoopTaskA());
execService.execute(new LoopTaskA());
execService.shutdown();
execService.execute(new LoopTaskA()); // throws exception in the console because once shutdown method is called, it does not accept any more tasks.
}
}

Comments

Popular posts from this blog

Bash - Execute Pl/Sql script from Shell script

Gradle Fundamentals

Load Balancing using Spring Cloud Netflix Ribbon