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:
- New
- Runnable
- Running
- Non-Runnable (Blocked)
- 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:
- By extending the Thread class
- 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...