In Java as per the requirement a developer can create their own thread to perform a task and that thread is called User-Define Thread.
In Java we have 2 different ways to create a User-Define Thread.
1. By extending the java.lang.Thread class
2. By implementing the java.lang.Runnable Interface.
Ques:-How we can create a User-Define thread by extending java.lang.Thread class?
As we know, in Java, a Thread is an object of the java.lang.Thread class. Therefore, when we create a user-defined thread, it will always be a subclass or associated with the java.lang.Thread class.
class Thread1 extends Thread{
}
class JTC{
public static void main(String arg[]){
Thread1 t1 = new Thread1();
System.out.println(t1);
}
}
Thread[Thread-0,5,main]
In this example as we can see we have a class Thread1 which is the sub class of java.lang.Thread class and we are creating an object of Thread1 and actually that object is a User-define Thread in the next example we will customize the user-define thread.
class Thread1 extends Thread{
}
class JTC{
public static void main(String arg[]){
Thread1 t1 = new Thread1();
t1.setName("My-First-User-Define-Thread");
t1.setPriority(7);
System.out.println(t1);
}
}
Thread[My-First-User-Define-Thread,7,main]
In this example, we set a custom thread name and thread priority using the setName() and setPriority() methods, respectively.
Now, we will configure the task according to the business logic for our user-defined thread. To define the task, it is necessary to override the run() method of the java.lang.Thread class in the subclass, which is the Thread1 class.
Note:- As we briefly discussed earlier, in Java, when a thread executes, it depends on the CPU scheduler. There is no need to invoke the run() method manually; it will be automatically invoked when our user-defined thread gets CPU time.
We will delve into topics such as CPU time and CPU scheduling algorithms in the Thread Life-Cycle tutorial.
class Thread1 extends Thread{
public void run(){
System.out.println("User-Define Thread is performming their task.....");
System.out.println("Current Thread Name :- "+this.getName());
System.out.println("Current Thread Priority :- "+this.getPriority());
System.out.println("Surrent Thread Thread-Group :- "+this.getThreadGroup().getName());
}
}
class JTC{
public static void main(String arg[]){
Thread1 t1 = new Thread1();
t1.setName("My-First-User-Define-Thread");
t1.setPriority(7);
t1.start();
}
}
User-Define Thread is performming their task..... Current Thread Name :- My-First-User-Define-Thread Current Thread Priority :- 7 Surrent Thread Thread-Group :- main
In this example, as we can see, we are overriding the run() method in the Thread1 class to provide a custom task where we print the details of the current thread.
In the main method, we do not explicitly invoke the run() method, yet the processing occurs. There is a method in the java.lang.Thread class called start(). When we invoke the start() method, the current working thread of start() transitions into the Ready-to-Run state. Moving into the Ready-to-Run state doesn't mean that the thread immediately receives CPU time and the run() method starts. In fact, when a thread moves to the Ready-to-Run state, it waits for its CPU time. Once it obtains its CPU time, the run() method is executed. The exact timing is unpredictable and depends on the current CPU scheduling algorithm.
Ques:- How we can create a User-Define thread by implementing java.lang.Runnable Interface?
In Java, we can create a User-Defined Thread by implementing the java.lang.Runnable interface.
java.lang.Runnable:
public interface java.lang.Runnable {
public abstract void run();
}
As we can see, there is only one abstract method in the java.lang.Runnable interface. Therefore, when we create a User-Defined Thread by implementing the java.lang.Runnable interface, we must override the run() method in the subclass.
An important point to understand is that since a thread is an object of the Thread class or its subclass, when we create an object of a User-Defined Thread class that implements java.lang.Runnable, we must create an object of the Thread class using the Thread class constructor.
public java.lang.Thread(java.lang.Runnable);
class Thread1 implements Runnable{
public void run(){
System.out.println("User-Define Thread is performming their task.....");
}
}
class JTC{
public static void main(String arg[]){
Thread1 t1 = new Thread1();
Thread th = new Thread(t1);
th.start();
}
}
User-Define Thread is performming their task.....
In this example, as we can see, we define a class Thread1 that implements the java.lang.Runnable interface. As discussed, we must associate a Thread1 class object with an object of the java.lang.Thread class, as demonstrated in the main method.
Thread1 t1 = new Thread1 ();
Thread th = new Thread (t1);
And finally we are starting a thread by invoking start () method of java.lang.Thread class.
Ques:-Why we have 2 different approaches to create a User-Define Thread in Java?
We know that in Java, we can't achieve multiple inheritance using classes. So, when we create a User-Defined thread by extending the java.lang.Thread class, there is no opportunity to inherit another class, according to our business logic. On the other hand, when we create a User-Defined thread by implementing the java.lang.Runnable interface, the subclass or User-Defined thread class can inherit from another class on demand