Data Types and Operators
(Non-Primitive Data Types)
Control Flow Statements
Conditional Statements
Looping Statements
Branching Statements
Object-Oriented Programming (OOP)
Exception Handling
Collections Framework
Overview of Collections
Java I/O
Multithreading
GUI Programming with Swing
Advanced Topics
JAVA CODE
Java Basics
Working with Objects
Arrays, Conditionals, and Loops
Creating Classes and Applications in Java
More About Methods
Java Applet Basics
Graphics, Fonts, and Color
Simple Animation and Threads
More Animation, Images, and Sound
Managing Simple Events and Interactivity
Creating User Interfaces with the awt
Windows, Networking, and Other Tidbits
Modifiers, Access Control, and Class Design
Packages and Interfaces
Exceptions
Multithreading
Streams and I/O
Using Native Methods and Libraries
Under the Hood
Java Programming Tools
Working with Data Structures in Java
Advanced Animation and Media
Fun with Image Filters
Client/Server Networking in Java
Emerging Technologies
appendix A :- Language Summary
appendix B :- Class Hierarchy Diagrams
appendix C The Java Class Library
appendix D Bytecodes Reference
appendix E java.applet Package Reference
appendix F java.awt Package Reference
appendix G java.awt.image Package Reference
appendix H java.awt.peer Package Reference
appendix I java.io Package Reference
appendix J java.lang Package Reference
appendix K java.net Package Reference
appendix L java.util Package Reference
In Java, there are two primary ways to create threads: by extending the ‘Thread class and by implementing the ‘Runnable interface. Both methods enable concurrent execution of code, but they have different use cases and advantages. Let’s delve into each approach in detail with examples.

1. Extending the Thread Class

When you extend the ‘Thread‘ class, you create a new class that inherits from ‘Thread‘ and override its ‘run‘ method to define the code that should be executed in the thread.

Steps:

  1. Extend the ‘Thread‘ class.
  2. Override the ‘run‘ method with the code to be executed.
  3. Create an instance of the new class.
  4. Call the ‘start‘ method on the instance to begin execution.

Example:

				
					class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
            try {
                Thread.sleep(1000); // Sleep for 1 second
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        
        thread1.start(); // Start the first thread
        thread2.start(); // Start the second thread
    }
}

				
			

2. Implementing the 'Runnable' Interface

When you implement the ‘Runnable‘ interface, you define the ‘run‘ method in a class and pass an instance of this class to a ‘Thread‘ object. This approach is preferred when you need to extend another class since Java supports single inheritance.

Steps:

  1. Implement the ‘Runnable‘ interface.
  2. Override the ‘run‘ method with the code to be executed.
  3. Create an instance of the class that implements ‘Runnable‘.
  4. Pass this instance to a ‘Thread‘ object.
  5. Call the ‘start‘ method on the ‘Thread‘ object to begin execution.

Example:

				
					class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
            try {
                Thread.sleep(1000); // Sleep for 1 second
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread1 = new Thread(myRunnable);
        Thread thread2 = new Thread(myRunnable);
        
        thread1.start(); // Start the first thread
        thread2.start(); // Start the second thread
    }
}

				
			

Comparison and Considerations

1. Extending Thread:

  • Pros:
    • Simplicity: Easier to use if you do not need to extend another class.
    • Direct access to thread methods like start, sleep, etc.
  • Cons:
    • Single inheritance limitation: Your class cannot extend any other class.
    • Tight coupling with thread implementation.

2. Implementing Runnable:

  • Pros:
    • More flexible: Can extend another class.
    • Better separation of concerns: The task to be performed is separate from the thread management.
    • More reusable: The Runnable implementation can be passed to different Thread instances.
  • Cons:
    • Slightly more boilerplate code: Need to create a Thread instance and pass the Runnable to it.

When to Use Which Approach

  • Use extending Thread when you have simple tasks and don’t need to extend any other class.
  • Use implementing Runnable when you need to extend another class or prefer a cleaner separation between the task and the thread management.

Both methods ultimately achieve the same goal of running code concurrently, but choosing the right one can help keep your code more organized and maintainable.

Scroll to Top