Java Threads
Threads in javapermits a program to operate more creatively at the same time multiple things. It can be used to perform complex tasks in the background without disturbing the main program.
How to create a thread: There are two ways to create a thread,
- Extend Thread class
- Implement Runnable interface.
Thread can be created by extending the Thread class and overriding its run () method:
Thread class: Thread class deliver constructors and methods to extends Object class and implements Runnable interface.
Frequently used Constructors of Thread class:
- Thread()
- Thread(String name)
- Thread(Runnable r)
- Thread(Runnable r, String name)
Frequently used methods of Thread class:
- public void run()This method used to perform action for a thread.
- public void start(): starts the execution of the thread.JVM calls the run() method on the thread.
- public void sleep(long miliseconds): Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds.
- public void join(): waits for a thread to die.
- public void join(long miliseconds): waits for a thread to die for the specified miliseconds.
- public int getPriority(): This method is the priority of the thread.
- public int setPriority(int priority): changes the priority of the thread.
- public String getName(): This method is the name of the thread.
- public void setName(String name): changes the name of the thread.
- public Thread currentThread(): This method is the reference of currently executing thread.
- public int getId(): This method is the id of the thread.
- public Thread.State getState(): This method is the state of the thread.
- public boolean isAlive(): tests if the thread is alive.
- public void yield():It causes the currently executing thread object to temporarily pause and allow other threads to execute.
- public void suspend(): This method used to suspend the thread(depricated).
- public void resume(): This method used to resume the suspended thread(depricated).
- public void stop(): This method used to stop the thread(depricated).
- public boolean isDaemon():It tests if the thread is a daemon thread.
- public void setDaemon(boolean b):It marks the thread as daemon or user thread.
- public void interrupt(): This interrupts the thread.
- public boolean isInterrupted():It tests if the thread has been interrupted.
- public static boolean interrupted(): It tests if the current thread has been interrupted.
Syntax for Extend
public class ExMain extends Thread { public void run() { System.out.println("This code is running in a thread"); } }
Another way: To implement the Runnable interface. Syntax for Implement:
public class ExMain implements Runnable { public void run() { System.out.println("This code is running in a thread"); } }
Running Threads
To extends a Thread class, thread can be run creating an instance or object of the class and call its start() method:
Extends Example
public class ExMain extends Thread { public static void main(String[] args) { ExMain thread = new ExMain (); thread.start(); System.out.println("This code is outside of the thread"); } public void run() { System.out.println("This code is running in a thread"); } }
This code is outside of the thread
This code is running in a thread.
If the class implements the Runnable interface, the thread can be run by passing an instance of the class to a Thread object’s constructor and then calling the thread’s start() method:
Implement Example
public class Main implements Runnable { public static void main(String[] args) { Main obj = new Main(); Thread thread = new Thread(obj); thread.start(); System.out.println("This code is outside of the thread"); } public void run() { System.out.println("This code is running in a thread"); } }
OUTPUT
This code is outside of the thread
This code is running in a thread.
F&Q (Frequently ask questions)
What is Extending and implementing?
The major difference is that when a class extends the Thread class cannot extend any other class, but by implementing the Runnable interface, it is possible to extend from another class as well, like: class ExClass extends NextClass implements Runnable.
Runnable interface:
The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. Runnable interface have only one method named run().
- public void run()This method used to perform action for a thread.
Starting a thread:
start() method of Thread class is used to start a newly created thread. It performs following tasks:
- A new thread starts that is with new callstack.
- The thread moves from New state to the Runnable state.
- When the thread gets a chance to execute, its target run() method will run.
1) Java Thread Example by extending Thread class
class multipleThread extends Thread{ public void run(){ System.out.println("thread is running..."); } public static void main(String args[]){ multipleThread t1=new multipleThread (); t1.start(); } }
Output:
thread is running…
2) Java Thread Example by implementing Runnable interface
class multiThread3 implements Runnable{ public void run(){ System.out.println("thread is running..."); } public static void main(String args[]){ multiThread3 m3=new multiThread3(); Thread t1 =new Thread(m3); t1.start(); } }
Output:thread is running…
If not extending the Thread class, object would not be preserved as a thread object. So need to explicitely create Thread class object. Passing the object of class that implements Runnable so that class run() method may execute.
Thread Scheduler in Java:
This is the part of the JVM Java virtual Machine that decides which thread should run. There is no promise that which runnable thread will be chosen to run by the thread scheduler. Only one thread at a time can run in a single process. The thread scheduler mainly uses preemptive or time slicing scheduling to schedule the threads.
Difference between preemptive scheduling and time slicing
Preemptive scheduling allows the highest priority task executes until it pass in the waiting or dead states or a higher priority task comes into existence. Time slicing is a task executes for a predefined slice of time and then returns the pool of ready tasks. The scheduler then governs which task should execute next, based on priority and other factors.
Sleep method:
In java the sleep() method of Thread class is used to sleep a thread for the specified amount of time.
Syntax of sleep() method: The Thread class provides two methods for sleeping a thread:
- public static void sleep(long miliseconds)throws InterruptedException
- public static void sleep(long miliseconds, int nanos)throws InterruptedException
Example of sleep method in java
class testSleep1 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[]){ testSleep1 t1=new testSleep1 (); testSleep1 t2=new testSleep1 (); t1.start(); t2.start(); } }
Output:
1
1
2
2
3
3
4
4
As at a time only one thread is executed. If the sleep method in a thread for the specified time, the thread scheduler choices another thread and so on.
Does start a thread twice? This is definitely no. After starting a thread, it can never be started again. If does so, an IllegalThreadStateException is thrown. In such case, thread will run once but for second time, it will throw exception.Let’s understand it by the example given below:
public class runThreadTwice extends Thread{ public void run(){ System.out.println("running..."); } public static void main(String args[]){ runThreadTwice t1=new runThreadTwice (); t1.start(); t1.start(); } }
OUTPUT:
running
Exception in thread “main” java.lang.IllegalThreadStateException
Does run() method call directly instead start() method?
Each thread starts in a separate call stack. Invoking the run() method from main thread, the run() method goes onto the current call stack rather than at the beginning of a new call stack.
class runCall extends Thread{ public void run(){ System.out.println("running..."); } public static void main(String args[]){ runCall t1=new runCall (); t1.run();//fine, but does not start a separate call stack } }
Output:running…
MainThreadStack Problem if direct call run() method
class runCall1 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[]){ runCall1 t1=new runCall1 (); runCall1 t2=new runCall1 (); t1.run(); t2.run(); } }
Output:
1
2
3
4
5
1
2
3
4
5
In the above program, there is no context-switching because here t1 and t2 will be treated as normal object not thread object.
The join() method:
The join() method waits for a thread to die. On the other hand, it origins the currently running threads to stop executing until the thread it joins with completes its task.
Syntax:
public void join()throws InterruptedException public void join(long milliseconds)throws InterruptedException.
Example of join() method
class runJoin1 extends Thread{ public void run(){ for(int i=1;i<=5;i++){ try{ Thread.sleep(500); }catch(Exception e){System.out.println(e);} System.out.println(i); } } public static void main(String args[]){ runJoin1 t1=new runJoin1 (); runJoin1 t2=new runJoin1 (); runJoin1 t3=new runJoin1 (); t1.start(); try{ t1.join(); }catch(Exception e){System.out.println(e);} t2.start(); t3.start(); } }
Output:
1
2
3
4
5
1
1
2
2
3
3
4
4
5
5
As in the above example, when t1 completes its task then t2 and t3 starts executing.
Example of join(long miliseconds) method
class runJoin2 extends Thread{ public void run(){ for(int i=1;i<=5;i++){ try{ Thread.sleep(500); }catch(Exception e){System.out.println(e);} System.out.println(i); } } public static void main(String args[]){ runJoin2 t1=new runJoin2 (); runJoin2 t2=new runJoin2 (); runJoin2 t3=new runJoin2 (); t1.start(); try{ t1.join(1500); }catch(Exception e){System.out.println(e);} t2.start(); t3.start(); } }
Output:
1
2
3
1
4
1
2
5
2
3
3
4
4
5
5
In the example, when t1 is completes its task for 1500 miliseconds that is 3 times then t2 and t3 starts executing.
getName(),setName(String) and getId() method:
public String getName()
public void setName(String name)
public long getId()
class runJoin3 extends Thread{ public void run(){ System.out.println("running..."); } public static void main(String args[]){ runJoin3 t1=new runJoin3(); runJoin3 t2=new runJoin3(); System.out.println("Name of t1:"+t1.getName()); System.out.println("Name of t2:"+t2.getName()); System.out.println("id of t1:"+t1.getId()); t1.start(); t2.start(); t1.setName("Md Harun"); System.out.println("After changing name of t1:"+t1.getName()); } }
Output:
Name of t1:Thread-0
Name of t2:Thread-1
id of t1:8
running…
After changling name of t1:Md Harun
running…
The currentThread() method: The method is a reference to the presently executing thread object.
Syntax:
public static Thread presentThread() Example of presentThread () method class runJoin4 extends Thread{ public void run(){ System.out.println(Thread.currentThread().getName()); } } public static void main(String args[]){ runJoin4 t1=new runJoin4 (); runJoin4 t2=new runJoin4 (); t1.start(); t2.start(); } }
Output:
Thread-0
Thread-1
Naming a Thread:
The Thread class delivers methods to modification and get the name of the thread. Each thread has a name that is thread-0, thread-1 and more on. By change the name of the thread by using setName() method. The syntax of setName() and getName() methods are given below:
public String getName(): This method used to return the name of a thread. public void setName(String name) : This method used to change the name of a thread.
Example of naming a thread
class RunMultiName1 extends Thread{ public void run(){ System.out.println("running..."); } public static void main(String args[]){ RunMultiName1 t1=new RunMultiName1 (); RunMultiName1 t2=new RunMultiName1 (); System.out.println("Name of t1:"+t1.getName()); System.out.println("Name of t2:"+t2.getName()); t1.start(); t2.start(); t1.setName("Md Harun"); System.out.println("After changing name of t1:"+t1.getName()); } }
Output:
Name of t1:Thread-0
Name of t2:Thread-1
id of t1:8
running…
After changeling name of t1: Md Harun
running…
Current Thread: The currentThread() method is a reference of currently executing thread.Example
public static Thread presentThread() Example of presentThread() method class RunMultiName2 extends Thread{ public void run(){ System.out.println(Thread.currentThread().getName()); } public static void main(String args[]){ RunMultiName2 t1=new RunMultiName2 (); RunMultiName2 t2=new RunMultiName2 (); t1.start(); t2.start(); } }
Output:
Thread-0
Thread-1
Priority of a Thread Or Thread Priority:
Each thread have a priority and are represented by a number between 1 and 10. In most cases, thread schedular are schedules the threads according to their priority known as preemptive scheduling. Though it is not guaranteed cause it depends on JVM specification that which scheduling it chooses.
3 constants defined in Thread class:
public static int MIN_PRIORITY
public static int NORM_PRIORITY
public static int MAX_PRIORITY
Default priority of a thread is 5 is NORM_PRIORITY. The value of MIN_PRIORITY is 1 and the value of MAX_PRIORITY is 10.
Example of priority of a Thread:
class RunMultiPriority1 extends Thread{ public void run(){ System.out.println("running thread name is:"+Thread.currentThread().getName()); System.out.println("running thread priority is:"+Thread.currentThread().getPriority()); } public static void main(String args[]){ RunMultiPriority1 m1=new RunMultiPriority1(); RunMultiPriority1 m2=new RunMultiPriority1(); m1.setPriority(Thread.MIN_PRIORITY); m2.setPriority(Thread.MAX_PRIORITY); m1.start(); m2.start(); } }
Output:
running thread name is:Thread-0
running thread priority is:10
running thread name is:Thread-1
running thread priority is:1
Daemon Thread:
In java is a service provider thread that provides services to the user thread. Its life depend on the mercy of user threads that is when all the user threads dies, JVM terminates this thread repeatedly.There are many java daemon threads running automatically for example gc, finalizer etc.
Key remember for Daemon Thread in Java:
- It provides services to user threads for background supporting tasks. It has no role in life than to serve user threads.
- Its life depends on user threads.
- It is a low priority thread.
Why JVM terminates the daemon thread if there is no user thread?
The only purpose of the daemon thread is provides services to user thread for background supporting task. If there is no user thread, why should JVM keep running this thread? That is why JVM terminates the daemon thread if there is no user thread.
Methods for Java Daemon thread by Thread class
The java.lang.Thread class provides two methods for java daemon thread.
- public void setDaemon(boolean status) method is used to mark the current thread as daemon thread or user thread.
- public boolean isDaemon() method is used to check that current is daemon.
Simple example of Daemon thread in java
public class RunDaemonThread extends Thread{ public void run(){ if(Thread.currentThread().isDaemon()){ //check daemon thread System.out.println("daemon thread work"); } else { System.out.println("user thread work"); } } public static void main(String[] args){ RunDaemonThread t1=new RunDaemonThread ();//creating thread RunDaemonThread t2=new RunDaemonThread (); RunDaemonThread t3=new RunDaemonThread (); t1.setDaemon(true);//now t1 is daemon thread t1.start();//starting threads t2.start(); t3.start(); } }
Output
daemon thread work
user thread work
user thread work
If want to make a user thread as Daemon, it must not be started otherwise it will throw IllegalThreadStateException.
class RunDaemonThread2 extends Thread{ public void run(){ System.out.println("Name: "+Thread.currentThread().getName()); System.out.println("Daemon: "+Thread.currentThread().isDaemon()); } public static void main(String[] args){ RunDaemonThread2 t1=new RunDaemonThread2 (); RunDaemonThread2 t2=new RunDaemonThread2 (); t1.start(); t1.setDaemon(true);//will throw exception here t2.start(); } }
Output:
exception in thread main: java.lang.IllegalThreadStateException
Java Thread Pool:
It is represents a group of worker threads that are waiting for the job and reprocess many times.In thread pool group of static size threads are created. A thread from the thread pool is pulled out and assigned a job by the service provider. After completion of the job, thread is contained in the thread pool again.
Advantage of Java Thread Pool
- Better performance and saves time because there is no need to create new thread.
- Real time usage
- It is recycled in Servlet and JSP where container creates a thread pool to process the request.
Example of Java Thread Pool
Let’s see a simple example of java thread pool using ExecutorService and Executors.
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class workersThread implements Runnable { private String message; public workersThread (String s){ this.message=s; } public void run() { System.out.println(Thread.currentThread().getName()+" (Start) message = "+message); processmessage();//call processmessage method that sleeps the thread for 2 seconds System.out.println(Thread.currentThread().getName()+" (End)");//prints thread name } private void processmessage() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }
AnotherExample.java
public class RunThreadPool { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(5);//creating a pool of 5 threads for (int i = 0; i < 10; i++) { Runnable worker = new WorkerThread("" + i); executor.execute(worker);//calling execute method of ExecutorService } executor.shutdown(); while (!executor.isTerminated()) { } System.out.println("Finished all threads"); } }
Output:
pool-1-thread-1 (Start) message = 0
pool-1-thread-2 (Start) message = 1
pool-1-thread-3 (Start) message = 2
pool-1-thread-5 (Start) message = 4
pool-1-thread-4 (Start) message = 3
pool-1-thread-2 (End)
pool-1-thread-2 (Start) message = 5
pool-1-thread-1 (End)
pool-1-thread-1 (Start) message = 6
pool-1-thread-3 (End)
pool-1-thread-3 (Start) message = 7
pool-1-thread-4 (End)
pool-1-thread-4 (Start) message = 8
pool-1-thread-5 (End)
pool-1-thread-5 (Start) message = 9
pool-1-thread-2 (End)
pool-1-thread-1 (End)
pool-1-thread-4 (End)
pool-1-thread-3 (End)
pool-1-thread-5 (End)
Finished all threads
ThreadGroup in Java
Java provides a convenient way to group multiple threads in a single object. In such way, we can suspend, resume or interrupt group of threads by a single method call. Now suspend(), resume() and stop() methods are deprecated. Java thread group is implemented by java.lang.ThreadGroup class. A ThreadGroup represents a set of threads. A thread group can also include the other thread group. The thread group creates a tree in which every thread group except the initial thread group has a parent. A thread is allowed to access information about its own thread group, but it cannot access the information about its thread group’s parent thread group or any other thread groups.
Constructors of ThreadGroup class
There are only two constructors of ThreadGroup class.
- ThreadGroup(String name) creates a thread group with given name.
- ThreadGroup(ThreadGroup parent, String name) creates a thread group with given parent group and name.
How to perform single task by multiple threads?
If you have to perform single task by many threads, have only one run() method.For example:
Program of performing single task by multiple threads
class RunMultitask1 extends Thread{ public void run(){ System.out.println("task one"); } public static void main(String args[]){ RunMultitask1 t1=new RunMultitask1 (); RunMultitask1 t2=new RunMultitask1 (); RunMultitask1 t3=new RunMultitask1 (); t1.start(); t2.start(); t3.start(); } }
Output:
task one
task one
task one
Program of performing single task by multiple threads
class RunMultitask2 implements Runnable{ public void run(){ System.out.println("task one"); } public static void main(String args[]){ Thread t1 =new Thread(new RunMultitask2());//passing annonymous object of TestMultitasking2 class Thread t2 =new Thread(new RunMultitask2()); t1.start(); t2.start(); } }
Output:
task one
task one
Here in the above example, each thread run in a separate callstack.
MultipleThreadsStack
How to perform multiple tasks by multiple threads or multitasking in multithreading?
If perform multiple tasks by multiple threads,have multiple run() methods. For example:
Program of performing two tasks by two threads
class run2Task2Thread extends Thread{ public void run(){ System.out.println("task one"); } } class run2Task2Thread extends Thread{ public void run(){ System.out.println("task two"); } } class RunMultitask3{ public static void main(String args[]){ Simple1 t1=new Simple1(); Simple2 t2=new Simple2(); t1.start(); t2.start(); } }
Output:
task one
task two
Same example as above by annonymous class that extends Thread class:
Program of performing two tasks by two threads
class RunMultitask4{ public static void main(String args[]){ Thread t1=new Thread(){ public void run(){ System.out.println("task one"); } }; Thread t2=new Thread(){ public void run(){ System.out.println("task two"); } }; t1.start(); t2.start(); } }
Output:
task one
task two
Same example as above by annonymous class that implements Runnable interface:
Program of performing two tasks by two threads
class RunMultitask5{ public static void main(String args[]){ Runnable r1=new Runnable(){ public void run(){ System.out.println("task one"); } }; Runnable r2=new Runnable(){ public void run(){ System.out.println("task two"); } }; Thread t1=new Thread(r1); Thread t2=new Thread(r2); t1.start(); t2.start(); } }
Output:
task one
task two