Multithreading Concepts in Java  

by ne on 2021-09-29 under Java

For Java thread basic, please read this : http://codinglords.com/blog/getById/3

To have details about Immutability and thread safety concepts, please read this series : http://codinglords.com/blog/getById/54

 

This article will primarily cover multithreading concepts, and some best practices for concurrency in Java.

It is divided into 4 sections:

  1. Basics

  2. UncaughtExceptionHandling for Threads

  3. Is DCL(double check locking) enough for Singletons ?

  4. Java Memory Model

 

Section-1 : Basics

A thread is a lightweight process in Java, which executes in parallel to the invocation process. Each thread has its own stack (which is not shared across different threads). Threads are scheduled by the underlying operating system only, and JVM guides the behavior of os-level-threads.

A thread in java can have 5 different states:

  1. New : just created thread object.
  2. Runnable : after start() method, or resumed(), notified()
  3. Non-Runnable : suspended, sleeping, waiting
  4. Running
  5. Terminated : when run() exits

You can refer to http://codinglords.com/blog/getById/3  to know about various ways to create threads

A basic class invoking a thread :

 


public static void main(String[] args){

    Thread thread=new Thread(new Runnable() {
        @Override
        public void run() {
            //some independent operation which can be done in parallel
            System.out.println("Hello world from a thread !");
        }
    });
    thread.start();
}

 

If run method finishes, the thread ends naturally. If we want to know the status of a thread , isAlive()  method returns true if the thread is still not terminated.

Thread Scheduling:

Each thread in java has a priority assigned from 1 to 10 (which we can change). The operating system decides which thread to run and when, and when to switch the threads and so on. But a high-priority thread can preempt a lower-priority thread at any time, and the operating system generally respects the priorities given.

 

Section 2 : Uncaught Exceptions

You may have encountered a scenario where an unchecked exception is thrown from a code which is executed by a different thread.

 


package com.codinglords;

/**
 * Created by naveensoni on 8/10/17.
 */
public class UncheckedException {

    public static void main(String[] args)  throws RuntimeException{
        UncheckedException ue=new UncheckedException();
        System.out.println("Test started");
        ue.methodInvokedInDifferentThread();
        System.out.println("Test finished");
    }

    public void methodInvokedInDifferentThread() throws RuntimeException{
        // do something silly
        throw new Exception("Thrown from the main thread");
    }
}

 

In the above code is executed, we will get the following output:

Test started


Exception in thread "main" java.lang.Exception: Thrown from a separate thread
    at com.codinglords.UncheckedException.methodInvokedInDifferentThread(UncheckedException.java:17)
    at com.codinglords.UncheckedException.main(UncheckedException.java:11)

But, if the same method was invoked from a thread :

Then, the output would be:


Exception in thread "Thread-0" java.lang.RuntimeException: Thrown from the main thread
    at com.codinglords.UncheckedException.methodInvokedInDifferentThread(UncheckedException.java:21)
    at com.codinglords.UncheckedException.lambda$main$0(UncheckedException.java:12)
    at java.lang.Thread.run(Thread.java:748)
Test finished

This time we were able to see Test finished, but why ?

Because in the first case, the exception was thrown back to the caller method, and eventually it reached main method. From main, we thrown it to JVM, and JVM crashed the program mentioning the exception.

But in the thread example, we exception was again sent back to original caller , which in this case was a thread only , And you can't throw any exception out of a thread by adding any throws clause. Because run() method's signature can't be changed. So , how to capture this exception ?

The Thread class provides a setUncaughtExceptionHandler() method, which is capable of capturing exceptions thrown by this thread, As below :

 


package com.codinglords;

/**
 * Created by naveensoni on 8/10/17.
 */
public class UncheckedException {

    public static void main(String[] args) throws Exception{
        UncheckedException ue=new UncheckedException();
        System.out.println("Test started");
        Thread t=new Thread(()->{
            ue.methodInvokedInDifferentThread();
        });
        t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable throwable) {
                System.out.println("Handling exception here");
            }
        });
        t.start();
        Thread.sleep(10000);
        System.out.println("Test finished");
    }

    public void methodInvokedInDifferentThread() throws RuntimeException{
        // do something silly
        throw new RuntimeException("Thrown from the main thread");
    }
}

Now the output becomes:

Test started
Handling exception here
Test finished

In this way, we can capture the uncaughtexceptions, thrown out in our thread.

 

Section 3 : Is DCL enough for Singletons ?

WIP

Section 4 : Java Memory Model

WIP