Ways to define a thread
- By extending Thread class
/**
* ChildThread
*/
public class ChildThread extends Thread{
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Child Thread");
}
}
public static void main(String[] args) {
// Create a child thread
ChildThread childThread = new ChildThread();
// start the thread
childThread.start();
for (int i = 0; i < 10; i++) {
System.out.println("Main Thread");
}
}
}
The Thread is an independent path of a program.
The output is unpredictable.
Case 1: Thread Scheduler
- Part of JVM
- Responsible to schedule threads.
- Cannot expect exact output, the execution order of the threads is decided by the Thread Scheduler.
Case 2: Difference between thread.start() and
thread.start() -> A new thread is created, and invokes the no-arg run() method of Thread class.
thread.run() -> A new thread is not created, and run() method will be executed just like a normal method call by Main Thread. Therefore, the output is predictable in this case.
Case 3: Importance of Thread Class start() method
Responsible to register the Thread with ThreadScheduler, and other mandatory activities.
Without start() method, there is no chance of creating a new thread.
start() {
// Register this thread with Thread Scheduler
// Perform all other mandatory activities
// Invoke run()
}
Case 4: Overloading of run() method
- If the run() method of the Thread class is overloaded in its child class, the main thread calls the overloaded methods as normal methods only. When we call start() method it will call no-arg run() method. Therefore, all overloaded run() methods are normal methods of the child class.
/**
* ChildThread
*/
public class ChildThread extends Thread{
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Child Thread");
}
} // Method called when start() method is called
public void run(int[] a) {
for (int i = 0; i < 10; i++) {
System.out.println("Child Thread");
}
} // Method called explicitly
public static void main(String[] args) {
// Create a child thread
ChildThread childThread = new ChildThread();
// start the thread
childThread.start();
for (int i = 0; i < 10; i++) {
System.out.println("Main Thread");
}
}
}
The output is no-arg run()
Case 5: Not overriding run()
- The Thread class has an empty implementation of run() method. If this method is overridden then there will be no output when start() method is invoked.
- If overriding of run() is done then better don't use MultiThreading concept.
/**
* ChildThread
*/
public class ChildThread extends Thread{
public static void main(String[] args) {
// Create a child thread
ChildThread childThread = new ChildThread();
// start the thread
childThread.start();
}
}
Output: No Output
Case 6: Overriding of start() method
- If the start() method is overridden, then it is executed just like a normal method, and no new thread will be created.
/**
* ChildThread
*/
public class ChildThread extends Thread{
@Override
public synchronized void start() {
System.out.println("Start Method");
}
@Override
public void run() {
System.out.println("Run Method");
}
public static void main(String[] args) {
// Create a child thread
ChildThread childThread = new ChildThread();
// start the thread
childThread.start();
}
}
Output: Start Method
Recommendation: Don't use MultiThreading Concept if you override start method.
Case 7: Thread Lifecycle
Case 8: After starting a thread if we try to restart the same thread, JVM will throw RE: java.lang.IllegalThreadStateException
/**
* ChildThread
*/
public class ChildThread extends Thread{
@Override
public void run() {
System.out.println("Run Method");
}
public static void main(String[] args) {
// Create a child thread
ChildThread childThread = new ChildThread();
// start the thread
childThread.start();
childThread.start(); // throws RuntimeException: java.lang.IllegalThreadStateException
}
}
Top comments (0)