Multithreading in Java

Multitasking is a process of executing one or more tasks concurrently or at a time. Similarly, multithreading is the process of executing one or more threads at the same time or concurrently.



Multitasking can be implanting in two ways:

  • Multiprocessing

  • Multithreading


multithreading in java

Multiprocessing Multithreading
  • Executing multiple programs or processes concurrently is called multiprocessing. These programs may be belong to the same programming language or a different one.
  • Executing multiple threads belonging to a single program or different programs which are implemented in same programming language is called multithreading.
  • Multiple programs running concurrently may occupy different memory spaces.
  • Different threads running concurrently may occupy a single memory space.
  • Context switching between processes is expensive.
  • Context switching between threads is easy and not expensive.
  • Data sharing between programs is expensive.
  • Data sharing threads is easy and cheap.

When we try to run any class

We need keep in mind the following: whenever main method get call automatically

public static void main (String [] args) {}

  1. Take the class name

  2. Take the command line value

  3. Creates the String array object

  4. If command line value is there then it stores command line value in String array

  5. Create the Thread group with name main

  6. Creates the Thread with :

    1. Name-main
    2. Priority-5
    3. Group-main

  7. Starts the main thread


Listed below are a few points that must be noted:

  • By default, JVM is created the main thread and is started, which is responsible for invoking the main method.

  • You can write your own threads which are called by user defined threads and are called as child threads.

  • You can also implement code for required tasks in the child threads.

  • The JVM always starts the main method and all child threads will also start from the main thread

    You can develop user defined threads in two way:
    • By extending java.lang.Thread class
    • By implementing java.lang.Runnable interface
Extending thread Implementing Runnable
Your user defined thread class has to extend java.lang.Thread Your user defined thread class has to implement java.lang.Runnable
From your thread class, you can invoke the following threads class constructors: Thread (string) and Thread (Thread Group, string). When your thread class is implementing Runnable interface, you have to explicitly create the thread with one of the following constructors:
  • Thread(Runnable) Thread(Runnable, string)
  • Thread (Thread Group, Runnable, string)
  • Thread (Thread Group, Runnable)
Example:
public class Demo extends Thread {
    public void run()  {   
}
public static void main(String args[]){
    Demo d1 = new Demo();
    d1.start();
  }
}
Example:
public class Demo implements Runnable
{
  public void run()  {  }
  public static void main(String args[]) {
    Demo d1 = new Demo();
    Thread t1 = new Thread(d1) // composition
    t1.start();
  }
}
  • When you create and start the thread, it will be placed in a ready to run state, and the thread will just wait for the CPU → start()

  • When the CPU scheduler allocates the CPU for them, t thread will be placed in running and be utilised by the CPU → run()

  • Depending on the CPU scheduling algorithm, the thread will be moved to ready to run from running state

  • When you call the sleep() method on the running thread, the thread will go into a sleep state and stay in that sleep state for a specified amount of time. Once the time is up, the thread will be moved into a ready to run state automatically

  • sleep() method will overload with the following version: void sleep(long)

    • The thread sleeps for specified amount of milliseconds and nano seconds void sleep(long , int)

  • When you call the wait() method during the running state, the thread will go into the wait state

  • To move the thread to wait, you can call one of the following methods of object class

    • void wait()
    • void wait(long)
    • void wait(long,int)

Thread waiting is in wait state there until either notify() or notifyAll() is called.

  • If notify() or notifyAll() is called before the specified amount of time, the thread will be moved to ready to run state

  • If specified amount of time is over without notifying, the thread will be moved to ready to run state automatically

  • When you call the notify() method, the thread which has been waiting for a long time in the wait state will be moved into the ready to run state

  • When you call the notifyAll() method, all the threads which are waiting will be moved to ready to run state

  • When a thread is waiting for an unavailable resource, the thread will be blocked and placed in blocked state. Later, when the requested resource is available, it will be moved to ready to run state

  • A blocked state is very dangerous since it may leads to deadlocks

Consider the following scenario: there are threads running concurrently. Call t1 and t2 and hold the resources called r1 and r2 respectively.

What would you do?  →    class A  t1
→ class B t2


The thread will be dead in two ways:
  1. It will be destroyed automatically whenever its task is completed (run () method execution is completed)
  2. You can destroy the thread before finishing its task by calling the destroy () method. Once it is dead, you cannot get it back to utilise the CPU time.

CPU schedulers are responsible for allocating CPU time for various processes or threads running in system. There FCFS or First Come First Served one is the simplest.

List of scheduling algorithms:

  • Shortest job first algorithm
  • First come first served schedulers
  • Time slice or round robin
  • Primitive scheduler algorithm
  • Non primitive scheduler algorithm

Thread Priority

Priority is a number assigned to the thread which will be used by the CPU scheduler to give more preference to the threads.


Can I overload run() method?

Yes, you can overload. But JVM calls the run() method whose signature is available in runnable interface i.e. public void run() and other overloaded methods should not be called by the JVM.

thread life cycle in java

Method Meaning
getName Obtain a thread's name
getPriority Obtain a thread's priority
isAlive Determine if a thread is still running
join Pause the current thread execution until the specified thread is dead
run Entry point for the thread
sleep Suspend a thread for a period of time
start Start a thread by calling its run method