Java Thread Class
Run each complete program separately. Its required helper classes and imports are included in the same code block. Short syntax fragments explain individual operations.
A thread lets a program make progress on a separate path of execution. For example, one task can prepare a result while another waits for input. Thread represents that running activity and provides operations for starting, observing, and coordinating it.
Instead of performing every task one after another, multiple threads can allow different tasks to make progress concurrently.
Java provides the Thread class to create and manage threads.
The Thread class belongs to the java.lang package.
Therefore, it does not need to be imported explicitly.
ThreadWhat is the Thread Class?
Thread is a class provided by Java that represents a thread of execution.
It provides methods for:
- Creating threads
- Starting threads
- Controlling thread execution
- Checking thread state
- Waiting for another thread
- Interrupting a thread
- Getting thread information
A simple thread can be created by extending the Thread class.
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running");
}
}Then:
MyThread thread = new MyThread();
thread.start();Why Do We Need Threads?
Consider a program that performs two independent tasks:
Task 1 → Download a file
Task 2 → Process dataWithout multiple threads, the program may execute them sequentially:
Task 1
↓
Task 2With multiple threads, both tasks can make progress concurrently:
Thread 1 → Download file
Thread 2 → Process dataThis can make applications more responsive and can improve throughput when tasks can execute concurrently.
However, using multiple threads also introduces challenges such as synchronization, shared data, and thread coordination.
Creating a Thread by Extending Thread
One way to create a thread is to extend the Thread class.
Example
class MyThread extends Thread {
@Override
public void run() {
System.out.println("My thread is running");
}
}
public class HelloWorld {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}Possible output:
My thread is runningThe important method here is run().
But we should not normally call run() directly to start a new thread.
Instead, we call start().
start() vs run()
This is one of the most important concepts when learning Java threads.
Using start()
thread.start();start() asks the JVM to start a new thread of execution, which will then invoke the thread's run() method.
Using run()
thread.run();Calling run() directly is just a normal method call. It does not start a new thread.
For example:
class MyThread extends Thread {
@Override
public void run() {
System.out.println(
"Running: " +
Thread.currentThread().getName()
);
}
}Then:
MyThread thread = new MyThread();
thread.run();The run() method executes on the current thread rather than starting a new thread.
But:
thread.start();starts a separate thread of execution.
Remember:
start()
↓
Starts a new thread
↓
run()Whereas:
run()
↓
Normal method call
↓
No new threadThe run() Method
The run() method contains the work that the thread should perform.
Example
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
}
}Then:
MyThread thread = new MyThread();
thread.start();The JVM executes the run() method on the newly started thread.
Naming a Thread
A thread can have a name.
Thread thread = new Thread();
thread.setName("Worker-Thread");
thread.start();Or a name can be supplied when creating the thread:
Thread thread =
new Thread("Worker-Thread");The thread name can be retrieved using:
thread.getName();Example
System.out.println(thread.getName());Thread.currentThread()
The currentThread() method returns the thread that is currently executing the code.
Example
class MyThread extends Thread {
@Override
public void run() {
Thread current =
Thread.currentThread();
System.out.println(
current.getName()
);
}
}If the thread is named Worker, the output may be:
WorkerA shorter version is:
System.out.println(
Thread.currentThread().getName()
);Main Thread
Every Java application starts with a thread that executes the main() method.
This is commonly called the main thread.
Example
public class HelloWorld {
public static void main(String[] args) {
System.out.println(
Thread.currentThread().getName()
);
}
}Typical output:
mainSo a simple Java application already has at least one thread: the main thread.
Creating Multiple Threads
We can create multiple thread objects.
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(
Thread.currentThread().getName()
+ " : "
+ i
);
}
}
}
public class HelloWorld {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.setName("Thread-1");
thread2.setName("Thread-2");
thread1.start();
thread2.start();
}
}The output order can vary because the threads are independently scheduled.
For example:
Thread-1 : 1
Thread-2 : 1
Thread-2 : 2
Thread-1 : 2
Thread-1 : 3
Thread-2 : 3Another execution may produce a different order.
Thread Scheduling
When multiple threads are running, the JVM and underlying operating system determine when each thread gets execution time.
Therefore, you should generally not assume a specific execution order between independently running threads.
For example:
thread1.start();
thread2.start();does not guarantee:
Thread-1
Thread-2in that exact execution order.
The scheduler may allow either thread to execute first or alternate between them.
Thread.sleep()
The sleep() method pauses the currently executing thread for approximately the specified duration.
Example
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}Here, Thread.sleep(1000) requests a pause of approximately 1000 milliseconds, or 1 second.
Important Point
sleep() affects the currently executing thread.
It does not cause the thread to permanently stop.
After the sleep duration expires, the thread becomes eligible to continue execution.
InterruptedException
The Thread.sleep() method can throw InterruptedException.
A common approach is:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}Restoring the interrupt status is important when the interruption should be propagated to code higher in the call chain.
Thread.join()
The join() method allows one thread to wait for another thread to finish.
Example
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}Now:
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
public class HelloWorld {
public static void main(String[] args)
throws InterruptedException {
MyThread thread = new MyThread();
thread.start();
thread.join();
System.out.println(
"Main thread continues"
);
}
}The main thread waits until thread terminates before continuing.
Simple idea:
Main Thread
|
| start
↓
Worker Thread
|
| completes
↓
Main Thread continuesThread.isAlive()
The isAlive() method checks whether a thread has been started and has not yet terminated.
Example
MyThread thread = new MyThread();
System.out.println(thread.isAlive());
thread.start();
System.out.println(thread.isAlive());The result can depend on the timing of execution, especially if the thread finishes very quickly.
Generally:
Before start() → false
While running → true
After termination → falseThread.getState()
The getState() method returns the current state of a thread.
Example
Thread thread = new Thread();
System.out.println(thread.getState());A newly created thread that has not been started is typically:
NEWJava Thread States
A Java thread can be in one of these Thread.State states:
- NEW
- RUNNABLE
- BLOCKED
- WAITING
- TIMED_WAITING
- TERMINATED
1. NEW
The thread object has been created but start() has not been called.
Thread thread = new Thread();State: NEW
2. RUNNABLE
After calling:
thread.start();the thread enters the RUNNABLE state.
This state represents a thread that is ready to run or is running under the JVM's scheduling model.
3. BLOCKED
A thread enters BLOCKED when it is waiting to acquire a monitor lock, typically to enter a synchronized block or method.
4. WAITING
A thread enters WAITING when it waits indefinitely for another thread to perform an action.
Examples include certain uses of Object.wait() and Thread.join() without a timeout.
5. TIMED_WAITING
A thread enters TIMED_WAITING when it waits for a specified amount of time.
Examples include Thread.sleep(1000); and thread.join(1000);.
6. TERMINATED
The thread has completed execution.
For example, after the run() method finishes, the thread eventually reaches TERMINATED.
A terminated thread cannot be started again.
Thread Priority
Java provides thread priority through setPriority() and getPriority().
Example
Thread thread = new Thread();
thread.setPriority(Thread.MAX_PRIORITY);
System.out.println(
thread.getPriority()
);Java defines these constants:
- Thread.MIN_PRIORITY
- Thread.NORM_PRIORITY
- Thread.MAX_PRIORITY
Their standard values are:
MIN_PRIORITY = 1
NORM_PRIORITY = 5
MAX_PRIORITY = 10Important Point
Thread priority should not be treated as a guarantee that one thread will always execute before another. Actual scheduling depends on the JVM and operating system.
Interrupting a Thread
Java provides interrupt() to request that a thread be interrupted.
Example
thread.interrupt();An interrupt is a cooperative mechanism. It does not forcibly terminate the thread.
For example, if a thread is sleeping:
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}the sleep can be interrupted.
The thread's interrupt status can also be checked using:
Thread.currentThread().isInterrupted()Can a Thread Be Started Twice?
No. A thread object can be started only once.
For example:
MyThread thread = new MyThread();
thread.start();
thread.start();The second call results in:
IllegalThreadStateExceptionIf another execution is required, create a new thread object.
MyThread thread1 = new MyThread();
thread1.start();
MyThread thread2 = new MyThread();
thread2.start();Thread Constructor
The Thread class provides several constructors.
Some commonly used forms include:
Thread() — Creates a thread with default settings.
Thread(String name) — Creates a thread with a specified name.
Thread(Runnable target) — Creates a thread associated with a Runnable task.
Thread(Runnable target, String name) — Creates a thread with a Runnable task and a specified name.
Example
Thread thread =
new Thread("Worker");
thread.start();Thread Using Runnable
Although this page focuses on the Thread class, an important alternative is implementing Runnable.
class MyTask implements Runnable {
@Override
public void run() {
System.out.println(
"Task is running"
);
}
}Then:
Thread thread =
new Thread(new MyTask());
thread.start();This approach separates the task from the thread that executes it.
It is often preferable to extending Thread, especially when the class already needs to extend another class.
Thread vs Runnable
| Thread | Runnable |
|---|---|
| Thread is a class | Runnable is an interface |
| Class extends Thread | Class implements Runnable |
| Cannot extend another class at the same time | Can still extend another class |
| Combines task and thread object | Separates task from thread |
| Useful for simple examples | Often preferred for reusable task definitions |
Example using Thread:
class MyThread extends Thread {
@Override
public void run() {
// task
}
}Example using Runnable:
class MyTask implements Runnable {
@Override
public void run() {
// task
}
}Thread Daemon
Java also supports daemon threads.
A daemon thread is a background thread that does not keep the JVM alive by itself once all non-daemon threads have terminated.
Example
Thread thread = new Thread(() -> {
while (true) {
System.out.println("Background work");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
});
thread.setDaemon(true);
thread.start();setDaemon(true) must be called before the thread is started.
thread.setDaemon(true);After a thread has started, its daemon status cannot be changed.
Thread Example: Performing Two Tasks
class TaskOne extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(
"Task One: " + i
);
}
}
}
class TaskTwo extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(
"Task Two: " + i
);
}
}
}
public class HelloWorld {
public static void main(String[] args) {
TaskOne taskOne = new TaskOne();
TaskTwo taskTwo = new TaskTwo();
taskOne.start();
taskTwo.start();
}
}The two tasks can execute concurrently, and their output order is not guaranteed.
Important Thread Methods
| Method | Purpose |
|---|---|
| start() | Starts a new thread of execution |
| run() | Contains the thread's task |
| sleep() | Pauses the currently executing thread for a specified duration |
| join() | Waits for another thread to terminate |
| interrupt() | Requests interruption of a thread |
| isInterrupted() | Checks the thread's interrupt status |
| isAlive() | Checks whether a thread is alive |
| currentThread() | Returns the currently executing thread |
| getName() | Returns thread name |
| setName() | Sets thread name |
| getPriority() | Gets thread priority |
| setPriority() | Sets thread priority |
| getState() | Gets current thread state |
| setDaemon() | Sets daemon status before start |
| isDaemon() | Checks whether thread is a daemon |
Common Mistakes with Thread
Mistake 1: Calling run() Instead of start()
Incorrect when the intention is to start a new thread:
thread.run();Correct:
thread.start();Mistake 2: Starting the Same Thread Twice
Incorrect:
thread.start();
thread.start();A thread object can only be started once.
Mistake 3: Assuming Thread Execution Order
Do not assume:
thread1.start();
thread2.start();means thread1 will always finish before thread2.
The actual execution order is affected by thread scheduling.
Mistake 4: Using sleep() as Synchronization
Thread.sleep() pauses execution for a period of time. It should not generally be used as a replacement for proper thread coordination or synchronization.
Thread Class vs ExecutorService
For learning the fundamentals of Java threads, the Thread class is important.
However, in larger applications, manually creating many threads can become difficult to manage.
Java provides higher-level concurrency APIs such as ExecutorService.
For example:
ExecutorService executor =
Executors.newFixedThreadPool(5);These APIs allow applications to manage reusable worker threads and submit tasks without manually creating a new Thread for every task.
Key Takeaway
The Java Thread class represents a thread of execution and provides methods for starting, monitoring, interrupting, and coordinating threads.
The most important concepts to remember are:
Thread
↓
start()
↓
New thread of execution
↓
run()
↓
Task executionRemember the most important distinction:
thread.start();starts a new thread, while:
thread.run();is simply a normal method call. For modern application development, understanding Thread provides the foundation for learning more advanced Java concurrency features such as Runnable, ExecutorService, synchronization, locks, Future, CompletableFuture, and concurrent collections.
See you in next page....🙂