Exams Knowledge Hub

MCQs for Competitive Exams, School & College Exams

Module: | Arrays, Strings & Exception Handling

Q50: Consider the following statements regarding thread creation via the Thread class and the Runnable interface:

1. Implementing the Runnable interface is generally preferred over extending the Thread class because Java strictly prohibits multiple class inheritance.
2. When a class extends the Thread class, it inherently tightly couples the concurrent task logic with the specific thread execution mechanism.
3. The Runnable interface contains multiple built-in lifecycle management methods such as start(), stop(), and suspend().

Which of the above statements is/are correct?
A
Only 1 and 2
B
Only 1 and 3
C
Only 2 and 3
D
1, 2, and 3
✅ Correct Answer: A
🎯 Quick Answer:
The correct combination is 1 and 2. Statement 3 is incorrect because the Runnable interface is a Functional Interface containing exactly one abstract method: run(). All lifecycle management methods (like start) belong strictly to the Thread class.
Concept Definition: In Java, multithreading can be initialized either by creating a subclass of java.lang.Thread or by creating a class that implements the java.lang.Runnable interface and passing an instance of it to a Thread object.
Structural Breakdown: Extending Thread: `class MyTask extends Thread { public void run() {} }`. Implementing Runnable: `class MyTask implements Runnable { public void run() {} }` followed by `new Thread(new MyTask()).start();`. Historical/Related Context: Because Java does not allow a class to inherit from more than one parent class, extending the Thread class permanently exhausts that class's single inheritance quota.
By implementing Runnable, the class remains free to inherit from a different domain-specific parent class (e.g., `class Player extends Character implements Runnable`). Causal Reasoning: The Runnable interface separates the "task" from the "worker." By decoupling the logic (Runnable) from the execution infrastructure (Thread), developers can easily pass Runnable tasks into modern, highly efficient thread pools (like ExecutorService) without manually spawning heavy Thread objects every time.