In Java, you can create a thread by extending the Thread
class or implementing the Runnable
interface. Both approaches involve overriding the run()
method, which contains the code that will be executed when the thread is started.
1. Extending the Thread
class:
class MyThread extends Thread {
public void run() {
// Code to be executed in the new thread
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
public class ThreadCreationExample {
public static void main(String[] args) {
// Create an instance of the custom thread
MyThread myThread = new MyThread();
// Start the thread
myThread.start();
// Code in the main thread
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
2. Implementing the Runnable
interface:
class MyRunnable implements Runnable {
public void run() {
// Code to be executed in the new thread
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
public class ThreadCreationExample {
public static void main(String[] args) {
// Create an instance of the class implementing Runnable
MyRunnable myRunnable = new MyRunnable();
// Create a Thread object, passing the Runnable instance
Thread myThread = new Thread(myRunnable);
// Start the thread
myThread.start();
// Code in the main thread
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
In both examples, the run()
method contains the code to be executed in the new thread. The start()
method is called to begin the execution of the thread. The Thread
class internally calls the run()
method, and the execution of the thread proceeds concurrently with the main thread.
Thread Naming:
Each thread has a name associated with it. By default, the threads are assigned names like “Thread-0,” “Thread-1,” and so on. You can set a custom name for a thread using the setName()
method:
myThread.setName("CustomThreadName");
Thread States:
A thread in Java can be in one of the following states:
- New: When the thread is created but not yet started.
- Runnable: When the thread is ready to run but is waiting for CPU time.
- Blocked: When the thread is waiting for a monitor lock to enter a synchronized block/method.
- Waiting: When the thread is waiting indefinitely for another thread to perform a particular action.
- Timed Waiting: When the thread is waiting for another thread to perform a particular action for a specified amount of time.
- Terminated: When the thread has completed its execution.
In summary, thread creation in Java involves either extending the Thread
class or implementing the Runnable
interface, with the run()
method containing the code to be executed in the new thread. The start()
method is then called to initiate the thread’s execution.
Java defines two ways to Create Thread in java
- implementing the Runnable interface
- Extend the Thread class, itself
Implementing Runnable
The easiest way to create a thread is to create a class that implements the Runnable interface. Runnable abstracts a unit of executable code. we can construct a thread on any object that implements Runnable. To implement Runnable, a class need only implement a single method called run( ), which is declared like this:
public void run( )
Inside run( ), we will define the code that constitutes the new thread. It is important to understand that run( ) can call other methods, use other classes, and declare variables, just like the main thread can. The only difference is that run( ) establishes the entry point for another, concurrent thread of execution within your program. This thread will end when run( ) returns
Example to implement Runnable
// Create a second thread.
class NewThread implements Runnable {
Thread t;
NewThread() {
// Create a new, second thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
Output
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Extending Thread
The second way to create a thread is to create a new class that extends Thread, and then to create an instance of that class. The extending class must override the run( ) method, which is the entry point for the new thread. It must also call start( ) to begin execution of the new thread
Example
class NewThread extends Thread {
NewThread() {
// Create a new, second thread
super("Demo Thread");
System.out.println("Child thread: " + this);
start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ExtendThread {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
Output
Creating Multiple Threads
Example to create multiple threads
class NewThread implements Runnable {
String name; // name of thread
Thread t;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name + "Interrupted");
}
System.out.println(name + " exiting.");
}
}
class MultiThreadDemo {
public static void main(String args[]) {
new NewThread("One"); // start threads
new NewThread("Two");
new NewThread("Three");
try {
// wait for other threads to end
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
The output from this program
New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
New thread: Thread[Three,5,main]
One: 5
Two: 5
Three: 5
One: 4
Two: 4
Three: 4
One: 3
Three: 3
Two: 3
One: 2
Three: 2
Two: 2
One: 1
Three: 1
Two: 1
One exiting.
Two exiting.
Three exiting.
Main thread exiting.