Basic introduction of multithreading in Java

Posted by techwiz on Mon, 07 Feb 2022 19:48:11 +0100

In Java, multithreading refers to the process of executing two or more threads at the same time to maximize the use of CPU. The thread in Java is a lightweight process, which only needs less resources to create and share process resources.

Multithreading and multiprocessing are used for multitasking in Java, but we prefer multithreading to multiprocessing. This is because threads use shared memory areas to help save memory, and content switching between threads is a little faster than processes.

Thread life cycle

A thread must go through five states in its life cycle. This lifecycle is controlled by the JVM (Java virtual machine). These states are:

  1. New
  2. Runnable
  3. Running
  4. Non-Runnable (Blocked)
  5. Terminated

New

In this state, a new Thread begins its life cycle. This is also called a new Thread. If you create an instance of the Thread class before calling the start() method, the Thread is in the newly created state.

Runnable

A thread becomes runnable after a newly generated thread is started. In this state, the thread will perform its tasks.

Running

When the thread scheduler selects a thread, the thread will be running.

Non-Runnable (Blocked)

The thread is still active in this state, but is not yet eligible to run.

Terminated

The thread terminated for the following reasons:

  • Its run() method either exists normally, that is, the code of the thread has executed the program.
  • Or due to some unusual errors, such as segmentation errors or unhandled exceptions.

Threads in the terminated state do not consume any cycles of the CPU.

Java thread class

The Java Thread class provides methods and constructors for creating and executing operations on threads. The Java Thread class extends the Object class and implements the Runnable interface.

Java Thread method

These are the methods available in the Thread class:

1. public void start()

It starts executing the Thread and then calls run() on the Thread object.

Example:

{    
    public void run()  
    {    
        System.out.println("Thread is running...");    
    }    
    public static void main(String[] args) {    
        StartExp1 thread1=new StartExp1();
        thread1.start();    
    }    
}

output

Thread is running...

2. public void run()

This thread is used to perform operations for the thread. If the thread is constructed with a separate Runnable object, instantiate the run() method.

Examples

public class RunExp1 implements Runnable  
{    
    public void run()  
    {    
        System.out.println("Thread is running...");    
    }    
    public static void main(String args[])  
    {    
        RunExp1 r1=new RunExp1();    
        Thread thread1 =new Thread(r1);    
        thread1.start();    
    }    
}  

output

Thread is running...

2. public void sleep()

This blocks the currently running thread for the specified time.

Examples

public class SleepExp1 extends Thread  
{    
    public void run()  
    {    
        for(int i=1;i<5;i++)  
        {    
            try 
            {  
                Thread.sleep(500);  
            }catch(InterruptedException e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {    
        SleepExp1 thread1=new SleepExp1();    
        SleepExp1 thread2=new SleepExp1();    
        thread1.start();    
        thread2.start();    
    }    
}  

output

1

1

2

2

3

3

4

4

4. public static Thread currentThread()

It returns a reference to the currently running thread.

Examples

public class CurrentThreadExp extends Thread  
{    
    public void run()  
    {    
        System.out.println(Thread.currentThread().getName());    
    }    
    public static void main(String args[])  
    {    
        CurrentThreadExp thread1=new CurrentThreadExp();    
        CurrentThreadExp thread2=new CurrentThreadExp();    
        thread1.start();    
        thread2.start();    
    }    
} 

output

Thread-0

Thread-1

5. public void join()

It causes the current thread to block until the second thread terminates or the specified number of milliseconds elapses.

Examples

public class JoinExample1 extends Thread  
{    
    public void run()  
    {    
        for(int i=1; i<=4; i++)  
        {    
            try 
            {    
                Thread.sleep(500);    
            }catch(Exception e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {   
        JoinExample1 thread1 = new JoinExample1();    
        JoinExample1 thread2 = new JoinExample1();    
        JoinExample1 thread3 = new JoinExample1();    
        thread1.start();   
       try 
        {    
        thread1.join();    
        }catch(Exception e){System.out.println(e);}    
        thread2.start();   
        thread3.start();    
    }    
}  

output

1

2

3

4

1

1

2

2

3

3

4

4

6. public final int getPriority()

It is used to check the priority of threads. When a thread is created, it is assigned some priority. This priority is explicitly assigned by the JVM or programmer when creating threads.

Examples

public class JavaGetPriorityExp extends Thread  
{    
    public void run()  
    {    
        System.out.println("running thread name is:"+Thread.currentThread().getName());    
    }    
    public static void main(String args[])  
    {    
        JavaGetPriorityExp t1 = new JavaGetPriorityExp();    
        JavaGetPriorityExp t2 = new JavaGetPriorityExp();    
        System.out.println("t1 thread priority : " + t1.getPriority());   
        System.out.println("t2 thread priority : " + t2.getPriority());  
        t1.start();    
        t2.start();  
    }    
}  

output

t1 thread priority : 5

t2 thread priority : 5

running thread name is:Thread-0

running thread name is:Thread-1

7. public final void setPriority()

This method is used to change the priority of a thread. The priority of each thread is represented by an integer from 1 to 10. The default priority for threads is 5.

Examples

public class JavaSetPriorityExp1 extends Thread  
{    
    public void run()  
    {    
        System.out.println("Priority of thread is: "+Thread.currentThread().getPriority());    
    }    
    public static void main(String args[])  
    {    
        JavaSetPriorityExp1 t1=new JavaSetPriorityExp1();
        t1.setPriority(Thread.MAX_PRIORITY);    
        t1.start();    
    }    
} 

output

Priority of thread is: 10

8. public final String getName()

This method of the thread class is used to return the name of the thread. We cannot override this method in our program because it is final.

Examples

public class GetNameExample extends Thread  
{    
    public void run()  
    {    
        System.out.println("Thread is running...");    
    }    
    public static void main(String args[])  
    {   
        // creating two threads   
        GetNameExample thread1=new GetNameExample();    
        GetNameExample thread2=new GetNameExample();    
        System.out.println("Name of thread1: "+ thread1.getName());    
        System.out.println("Name of thread2: "+thread2.getName());    
        thread1.start();    
        thread2.start();    
    }    
}

output

Name of thread1: Thread-0

Name of thread2: Thread-1

Thread is running...

Thread is running...

9. public final void setName()

This method changes the name of the thread.

Examples

public class SetNameExample extends Thread  
{    
    public void run()  
    {    
        System.out.println("running...");    
    }    
    public static void main(String args[])  
    {   
        SetNameExample thread1=new SetNameExample();    
        SetNameExample thread2=new SetNameExample();    
        thread1.start();    
        thread2.start();       
        thread1.setName("Kadamb Sachdeva");    
        thread2.setName("Great learning");  
        System.out.println("After changing name of thread1: "+thread1.getName());  
        System.out.println("After changing name of thread2: "+thread2.getName());  
    }    
}

output

After changing name of thread1: Kadamb Sachdeva

After changing name of thread2: Great Learning

running...

running...

10. public long getId()

It returns the identifier of the thread. Thread ID is a number generated when creating a thread. This ID cannot be changed during its lifecycle. However, when the thread terminates, the ID can be reused.

Examples

public class GetIdExample extends Thread  
{    
    public void run()  
    {    
        System.out.println("running...");    
    }    
    public static void main(String args[])  
    {    
        GetIdExample thread1=new GetIdExample();    
        System.out.println("Name of thread1: "+thread1.getName());  
        System.out.println("Id of thread1: "+thread1.getId());   
        thread1.start();  
    }    
}

output

Name of thread1: Thread-0

Id of thread1: 21

running...

11. public final boolean isAlive()

This method checks whether the thread is active. If the start() method of the thread class has been called and the thread has not died, the thread is active.

Examples

public class JavaIsAliveExp extends Thread   
{  
    public void run()  
    {  
        try  
        {  
            Thread.sleep(300);  
            System.out.println("is run() method isAlive "+Thread.currentThread().isAlive());  
        }  
        catch (InterruptedException ie) {  
        }  
    }  
    public static void main(String[] args)  
    {  
        JavaIsAliveExp thread1 = new JavaIsAliveExp();  
        System.out.println("before starting thread isAlive: "+thread1.isAlive());  
        thread1.start();  
        System.out.println("after starting thread isAlive: "+thread1.isAlive());  
    }  
} 

output

before starting thread isAlive: false

after starting thread isAlive: true

is run() method isAlive true

12. public static void yield()

This method pauses the execution of the current thread to temporarily execute other threads.

Examples

public class JavaYieldExp extends Thread  
{  
    public void run()  
    {  
        for (int i=0; i<3 ; i++)  
            System.out.println(Thread.currentThread().getName() + " in control");  
    }  
    public static void main(String[]args)  
    {  
        JavaYieldExp thread1 = new JavaYieldExp();  
        JavaYieldExp thread2 = new JavaYieldExp();  
        thread1.start();  
        thread2.start();  
        for (int i=0; i<3; i++)  
        {  
            thread1.yield();  
            System.out.println(Thread.currentThread().getName() + " in control");  
        }  
    }  
}

output

main in control

main in control

main in control

Thread-0 in control

Thread-0 in control

Thread-0 in control

Thread-1 in control

Thread-1 in control

Thread-1 in control

13. public final void suspend()

This method is used to temporarily suspend the currently running thread. Using the resume() method, you can resume the suspended thread.

Examples

public class JavaSuspendExp extends Thread  
{    
    public void run()  
    {    
        for(int i=1; i<5; i++)  
        {    
            try 
            {  
                 sleep(500);  
                 System.out.println(Thread.currentThread().getName());    
            }catch(InterruptedException e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {    
        JavaSuspendExp thread1=new JavaSuspendExp ();    
        JavaSuspendExp thread2=new JavaSuspendExp ();   
        JavaSuspendExp thread3=new JavaSuspendExp ();
        thread1.start();  
        thread2.start();  
        thread2.suspend();   
        thread3.start();  
    }    
}

output

Thread-0

1

Thread-2

1

Thread-0

2

Thread-2

2

Thread-0

3

Thread-2

3

Thread-0

4

Thread-2

4

14. public final void resume()

This method is used to resume a suspended thread. It is used only with the suspend() method.

public class JavaResumeExp extends Thread  
{    
    public void run()  
    {    
        for(int i=1; i<5; i++)  
        {    
            try 
            {  
                 sleep(500);  
                 System.out.println(Thread.currentThread().getName());    
            }catch(InterruptedException e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {    
        JavaResumeExp thread1=new JavaResumeExp ();    
        JavaResumeExp thread2=new JavaResumeExp ();   
        JavaResumeExp thread3=new JavaResumeExp ();   
        thread1.start();  
        thread2.start();  
        thread2.suspend();
        thread3.start();   
        thread2.resume();
    }    
}

output

Thread-0

1

Thread-2

1

Thread-1

1

Thread-0

2

Thread-2

2

Thread-1

2

Thread-0

3

Thread-2

3

Thread-1

3

Thread-0

4

Thread-2

4

Thread-1

4

15. public final void stop()

As the name suggests, this method is used to stop the currently running thread. Remember that once the thread execution stops, it cannot be restarted.

Examples

public class JavaStopExp extends Thread  
{    
    public void run()  
    {    
        for(int i=1; i<5; i++)  
        {    
            try 
            {  
                sleep(500);  
                System.out.println(Thread.currentThread().getName());    
            }catch(InterruptedException e){System.out.println(e);}    
            System.out.println(i);    
        }    
    }    
    public static void main(String args[])  
    {    
        JavaStopExp thread1=new JavaStopExp ();    
        JavaStopExp thread2=new JavaStopExp ();   
        JavaStopExp thread3=new JavaStopExp ();   
        thread1.start();  
        thread2.start();  
        thread3.stop();  
        System.out.println("Thread thread3 is stopped");    
    }    
}

16. public void destroy()

This thread method destroys thread groups and their subgroups.

Examples

public class JavaDestroyExp extends Thread   
{  
    JavaDestroyExp(String threadname, ThreadGroup tg)  
    {  
        super(tg, threadname);  
        start();  
    }  
    public void run()  
    {  
        for (int i = 0; i < 2; i++)   
        {  
            try 
            {  
                Thread.sleep(10);  
            }  
            catch (InterruptedException ex) {  
                System.out.println("Exception encounterted");}  
        }  
        System.out.println(Thread.currentThread().getName() +  
              " finished executing");  
    }  
    public static void main(String arg[]) throws InterruptedException, SecurityException  
    {  
        ThreadGroup g1 = new ThreadGroup("Parent thread"); 
        ThreadGroup g2 = new ThreadGroup(g1, "child thread");  
        JavaDestroyExp thread1 = new JavaDestroyExp("Thread-1", g1);  
        JavaDestroyExp thread2 = new JavaDestroyExp("Thread-2", g1);  
        thread1.join();  
        thread2.join();  
        g2.destroy();  
        System.out.println(g2.getName() + " destroyed");  
        g1.destroy();  
        System.out.println(g1.getName() + " destroyed");  
    }  
} 

output

Thread-1 finished executing

Thread-2 finished executing

child thread destroyed

Parent thread destroyed

17. public final boolean isDaemon()

This thread method checks whether the thread is a daemon thread. If it is a daemon thread, it returns true; otherwise, it returns false.

For those who do not know about daemon threads, daemon threads are threads that do not prevent the Java virtual machine (JVM) from exiting at the end of the program, but the threads are still running.

Examples

public class JavaIsDaemonExp extends Thread  
{    
    public void run()  
    {    
        //checking for daemon thread    
        if(Thread.currentThread().isDaemon())  
        {  
            System.out.println("daemon thread work");    
        }    
        else 
        {    
            System.out.println("user thread work");    
        }    
    }    
    public static void main(String[] args)  
    {    
        JavaIsDaemonExp thread1=new JavaIsDaemonExp();   
        JavaIsDaemonExp thread2=new JavaIsDaemonExp();    
        JavaIsDaemonExp thread3=new JavaIsDaemonExp();    
        thread1.setDaemon(true);  
        thread1.start();   
        thread2.start();    
        thread3.start();    
    }    
}

output

daemon thread work

user thread work

user thread work

18. public final void setDaemon(boolean on)

This method of thread is used to identify or mark whether the thread is a daemon or a user thread. When all user threads die, the JVM automatically terminates the thread.

The thread method must be run before the thread starts executing.

Examples

public class JavaSetDaemonExp1 extends Thread  
{    
    public void run()  
    {    
        if(Thread.currentThread().isDaemon())  
        {  
            System.out.println("daemon thread work");    
        }    
        else 
        {    
            System.out.println("user thread work");    
        }    
    }    
    public static void main(String[] args)  
    {    
        JavaSetDaemonExp1 thread1=new JavaSetDaemonExp1();   
        JavaSetDaemonExp1 thread2=new JavaSetDaemonExp1();    
        JavaSetDaemonExp1 thread3=new JavaSetDaemonExp1();    
        thread1.setDaemon(true);  
        thread1.start();   
        thread2.setDaemon(true);  
        thread2.start();    
        thread3.start();    
    }    
} 

output

daemon thread work

daemon thread work

user thread work

19. public void interrupt()

This method of thread is used to interrupt the thread currently executing. This method can only be called when the thread is sleeping or waiting.

However, if the thread is not sleeping or waiting, the interrupt() method does not interrupt the thread, but sets the interrupt flag to true.

Examples

public class JavaInterruptExp1 extends Thread  
{    
    public void run()  
    {    
        try 
        {    
            Thread.sleep(1000);    
            System.out.println("javatpoint");    
        }catch(InterruptedException e){    
            throw new RuntimeException("Thread interrupted..."+e);  
               
        }    
    }    
    public static void main(String args[])  
    {    
        JavaInterruptExp1 thread1=new JavaInterruptExp1();    
        thread1.start();    
        try 
        {    
            thread1.interrupt();    
        }catch(Exception e){System.out.println("Exception handled "+e);}    
    }    
}  

output

Exception in thread "Thread-0" java.lang.RuntimeException: Thread interrupted...java.lang.InterruptedException: sleep interrupted at JavaInterruptExp1.run(JavaInterruptExp1.java:10)

20. public boolean isInterrupted()

This thread method is used to test whether the thread is interrupted. It returns the value of the internal flag as true or false, that is, if the thread is interrupted, it will return true, otherwise it will return false.

Examples

public class JavaIsInterruptedExp extends Thread   
{   
    public void run()   
    {   
        for(int i=1;i<=3;i++)   
        {   
            System.out.println("doing task....: "+i);   
        }   
    }   
    public static void main(String args[])throws InterruptedException   
    {   
        JavaIsInterruptedExp thread1=new JavaIsInterruptedExp();   
        JavaIsInterruptedExp thread2=new JavaIsInterruptedExp();   
        thread1.start();   
        thread2.start();  
        System.out.println("is thread interrupted..: "+thread1.isInterrupted());  
        System.out.println("is thread interrupted..: "+thread2.isInterrupted());  
        thread1.interrupt();   
        System.out.println("is thread interrupted..: " +thread1.isInterrupted());   
        System.out.println("is thread interrupted..: "+thread2.isInterrupted());   
    }  
} 

output

is thread interrupted...: false

is thread interrupted...: false

is thread interrupted...: true

is thread interrupted...: false

doing task....: 1

doing task....: 2

doing task....: 3

doing task....: 1

doing task....: 2

doing task....: 3

21. public static boolean interrupted()

This thread method is used to check whether the current thread is interrupted. If you want to call this thread method twice in a row, the second call will return false.

If the interrupt state of the thread is true, the thread method will set it to false.

Examples

public class JavaInterruptedExp extends Thread   
{   
    public void run()   
    {   
        for(int i=1;i<=3;i++)   
        {   
            System.out.println("doing task....: "+i);   
        }   
    }   
    public static void main(String args[])throws InterruptedException   
    {   
        JavaInterruptedExp thread1=new JavaInterruptedExp();   
        JavaInterruptedExp thread2=new JavaInterruptedExp();   
        thread1.start();   
        thread2.start();  
        System.out.println("is thread thread1 interrupted..:"+thread1.interrupted()); 
        thread1.interrupt();   
        System.out.println("is thread thread1 interrupted..:"+thread1.interrupted());   
        System.out.println("is thread thread2 interrupted..:"+thread2.interrupted());   
    }  
} 

output

is thread thread1 interrupted...: false

is thread thread1 interrupted...: false

is thread thread2 interrupted...: false

doing task....: 1

doing task....: 2

doing task....: 3

doing task....: 1

doing task....: 2

doing task....: 3

22. public static int activeCount()

This method of thread is used to return the number of active threads in the thread group of the current executing thread.

The number returned by this thread method is only an estimate, because the number of threads will change dynamically when this method traverses the internal data structure.

Examples

public class JavaActiveCountExp extends Thread   
{  
    JavaActiveCountExp(String threadname, ThreadGroup tg)  
    {  
        super(tg, threadname);  
        start();  
    }  
    public void run()  
    {  
       System.out.println("running thread name is:"
+Thread.currentThread().getName());    
    }  
    public static void main(String arg[])  
    {  
        ThreadGroup g1 = new ThreadGroup("parent thread group");  
          JavaActiveCountExp thread1 = new JavaActiveCountExp("Thread-1", g1);  
        JavaActiveCountExp thread2 = new JavaActiveCountExp("Thread-2", g1);  
          System.out.println("number of active thread: "+ g1.activeCount());  
    }  
}

output

number of active thread: 2

running thread name is: Thread-1

running thread name is: Thread-2

23. public final void checkAccess()

This thread method identifies whether the current thread has permission to modify the thread.

Examples

public class JavaCheckAccessExp extends Thread     
{    
    public void run()  
    {  
        System.out.println(Thread.currentThread().getName()+" finished executing");  
    }  
    public static void main(String arg[]) throws InterruptedException, SecurityException    
    {   
        JavaCheckAccessExp thread1 = new JavaCheckAccessExp();    
        JavaCheckAccessExp thread2 = new JavaCheckAccessExp();    
        thread1.start();  
        thread2.start();  
        thread1.checkAccess();    
        System.out.println(t1.getName() + " has access");    
        thread2.checkAccess();    
        System.out.println(t2.getName() + " has access");    
    }    
}  

output

Thread-0 has access

Thread-1 has access

Thread-0 finished executing

Thread-1 finished executing

24. public static boolean holdsLock(Object obj)

This thread method checks whether the currently executing thread holds the monitor lock of the specified object. If so, the thread method will return true.

Examples

public class JavaHoldLockExp implements Runnable   
{  
    public void run()   
    {  
        System.out.println("Currently executing thread is: " + Thread.currentThread().getName());  
        System.out.println("Does thread holds lock? " + Thread.holdsLock(this));  
        synchronized (this)   
        {  
            System.out.println("Does thread holds lock? " + Thread.holdsLock(this));  
        }  
    }  
    public static void main(String[] args)   
    {  
        JavaHoldLockExp g1 = new JavaHoldLockExp();  
        Thread thread1 = new Thread(g1);  
        thread1.start();  
    }  
}

output

Currently executing thread is: Thread-0

Does thread holds lock? false

Does thread holds lock? true

In addition, there are a variety of threading methods for different tasks and purposes. These threading methods are as follows:

  • public static void dumpStack()
  • public StackTraceElement[] getStackTrace()
  • public static int enumerate(Thread[] tarray)
  • public Thread.State getState()
  • public final ThreadGroup getThreadGroup()
  • public String toString()
  • public final void notify()
  • public final void notifyAll()
  • public void setContextClassLoader(ClassLoader cl)
  • public ClassLoader getContextClassLoader()
  • public static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()
  • public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

Create thread

When using multithreading in Java, you can create threads in two ways:

  1. By extending the Thread class
  2. By implementing Runnable interface

What is the Thread class

The Thread class provides methods and constructors for creating and executing operations on threads. The Thread class extends the Object class and implements the Runnable interface.

Various constructors are used in Thread class, but common constructors are:

  • Thread()
  • Thread(String name)
  • Thread(Runnable r)
  • Thread(Runnable r,String name)

In addition, as mentioned earlier, there are a variety of threading methods for different purposes and tasks.

Therefore, these constructors and methods are provided by the Thread class to perform various operations on the Thread.

What is the Runnable interface

The Runnable interface is implemented, and its example is designed to be executed by threads. It has only one method, run().

public void run() this is used to perform operations for threads.

Start a thread

When multithreading in Java, to start a newly created thread, use the start() method.

  • A new thread starts (using the new call stack).
  • The thread moves from New state to Runnable state.
  • When a thread has a chance to execute, its target run() method will run.

Java Thread example by extending the Thread class

class Multi extends Thread{  
public void run(){  
System.out.println("thread is running...");  
}  
public static void main(String args[]){  
Multi thread1=new Multi();  
thread1.start();  
 }  
} 

output

thread is running...

Java thread example by implementing Runnable interface

class Multi3 implements Runnable{  
public void run(){  
System.out.println("thread is running...");  
}  
 
public static void main(String args[]){  
Multi3 m1=new Multi3();  
Thread thread1 =new Thread(m1);  
thread1.start();  
 }  
} 

output

thread is running...

Topics: Java Back-end