1. Introduction
A thread is a thread of execution in program. A thread is a light weight sub-process. It is smallest unit of processing.
- A thread has its own call stack and there is only one call stack per thread in Java.
- Thread in Java is represented by
java.lang.Thread
class. - Threads exist within a process. So every process has at least one thread. Every Java application has one or several threads.
- Threads are lightweight. Creating a new thread requires fewer resources than creating a new process.
- Threads share process’s resources like memory space.
- Context switching between threads is usually less expensive than switching between processes.
- Cost of intercommunication between threads is relatively low than that of communication between processes.
2. Create a thread
There are two ways to create thread in Java:
- By implementing the
Runnable
interface. - By extending
java.lang.Thread
class.
2.1 Create a thread by extending java.lang.Thread
To create a thread by extending Thread
class involved two steps:
- Extend
java.lang.Thread
class. - Override the
run()
method.
//Our thread class extending Thread class MyThread extends Thread { public void run() { System.out.println("executing thread"); } } public class ThreadExample { public static void main(String args[]) { //creating the thread MyThread myThread1 = new MyThread(); //start a thread myThread1.start(); } }
Output
executing thread
This approach has disadvantage that you can not extend any other class since you have already extended Thread
class.
2.2 Create a thread by implementing java.lang.Runnable
The approach to create a thread by implementing Runnable
interface is the preferred way of creating a thread. This approach allows you to extend another class.
You can create a thread by implementing Runnable
and then passing it to a Thread
. This approach separates the job of the thread and the instance creation of a thread.
This approach involves two steps:
- Define job of thread by creating a
Runnable
. - Create a thread by passing
Runnable
toThread
constructor.
//Define job performed by a thread class MyThread implements Runnable { public void run() { System.out.println("executing thread"); } } public class ThreadExample { public static void main(String args[]) { //Pass Runnable to Thread Thread t = new Thread(new MyThread()); //run a thread t.start(); } }
Output
executing thread
Note: Thread
class itself implements Runnable
interface.
3. Start a thread
public void run()
Creating a thread instance does not mean it is alive. It is just an instance. To make the thread alive, we have to start it manually.
To start a thread, you have to manually start the thread by calling start()
method on thread. If you call the run()
method directly, it will not create a new thread and no separate call stack will be created.
The Thread
class expects a run()
method with no arguments. run()
method is executed in a separate call stack once the thread has been started.
4. Points to note
- You can not start a
Runnable
. You can only start aThread
. - You can directly call
run()
method like any other method but it does not start a new thread and no separate stack is created.run()
method in this case goes onto current call stack. - Creating an object of the
Thread
class doesn’t create a new execution thread. - Calling the
run()
method of a class that implementsRunnable
doesn’t create a new execution thread. Thread is created only whenstart()
is called. - A thread can not be started twice. If you call
start()
method on a thread once the thread has been started, it will throwIllegalThreadStateException
which is aRuntimeException
. - Once
run()
method completes, it no longer remains a thread. - You can not call
start()
method twice even if therun()
method has not completed. - A Java program ends when all its non-daemon threads finish.
- If the initial thread ends, the rest of the thread continue with their execution until they finish. If one of the threads call
System.exit()
to end the execution, all other threads end their execution.
5. Order of execution of threads
The thread scheduler is responsible for deciding which thread out of multiple eligible runnable threads should execute at a given point of time. Eligible here means runnable threads not new and dead threads.
The order in which a runnable thread is chosen out of all eligible runnable threads to execute at a given point of time is not guaranteed. The thread scheduler can choose any of the eligible running threads.
The above statement is on the assumption that there is only one processor.
We can not control the behavior of the thread scheduler but we can influence using various methods.
- public final void setPriority(int newPriority)
- public final void join() throws InterruptedException
- public final void notify()
- public final void notifyAll()public static void sleep(long millis) throws InterruptedException
- public static void yield()
- public final void wait() throws InterruptedException
6. Thread Information
The Thread
class has some attributes which describe the information about the thread. These attributes are:
- ID: This is the unique identifier for each
Thread
. - Name: This is the name of the
Thread
. - Priority: Represents the priority of the
Thread
. It is a number between 1 and 10. 1 is the lowest priority and 10 is the highest priority. - Status: Represents the status of the
Thread
. A thread can be in one of these states: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED.