feat : complete Download Manager Simulator + bonus features
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# Theoretical Questions
|
||||
|
||||
## 1. start() vs run()
|
||||
|
||||
### Question 1: What output do you get from the program? Why?
|
||||
|
||||
output:
|
||||
|
||||
```text
|
||||
Calling run()
|
||||
Running in: main
|
||||
Calling start()
|
||||
Running in: Thread-2
|
||||
```
|
||||
|
||||
Explanation:
|
||||
|
||||
When `t1.run()` is called, the `run()` method executes like a normal method call in the current thread, which is the `main` thread. Therefore, `Thread.currentThread().getName()` returns `"main"`.
|
||||
When `t2.start()` is called, Java creates a new thread named `"Thread-2"` and executes the `run()` method inside that new thread. Therefore, the output shows `"Thread-2"`.
|
||||
|
||||
---
|
||||
|
||||
### Question 2: What’s the difference in behavior between calling start() and run()?
|
||||
|
||||
| start() | run() |
|
||||
| ----------------------------------- | --------------------------------------- |
|
||||
| Creates a new thread. | Does not create a new thread. |
|
||||
| Executes `run()` concurrently. | Executes `run()` in the current thread. |
|
||||
| Thread scheduler manages execution. | Behaves like a normal method call. |
|
||||
| Enables true multithreading. | No multithreading occurs. |
|
||||
|
||||
---
|
||||
|
||||
## 2. Daemon Threads
|
||||
|
||||
### Question 1: What output do you get from the program? Why?
|
||||
|
||||
Typical output:
|
||||
|
||||
```text
|
||||
Main thread ends.
|
||||
```
|
||||
|
||||
Or a few lines such as:
|
||||
|
||||
```text
|
||||
Daemon thread running...
|
||||
Main thread ends.
|
||||
```
|
||||
|
||||
Explanation:
|
||||
|
||||
The created thread is marked as a daemon thread using:
|
||||
|
||||
```java
|
||||
thread.setDaemon(true);
|
||||
```
|
||||
|
||||
A daemon thread runs in the background and does not prevent the JVM from shutting down. Once the `main` thread finishes, there are no user (non-daemon) threads left, so the JVM terminates immediately. As a result, the daemon thread may not complete all 20 iterations.
|
||||
|
||||
---
|
||||
|
||||
### Question 2: What happens if you remove thread.setDaemon(true)?
|
||||
|
||||
The thread becomes a normal user thread.
|
||||
|
||||
In that case, the JVM waits for the thread to finish before exiting. The program continues running for approximately 10 seconds (20 × 500 ms), and all 20 messages are printed.
|
||||
|
||||
Example output:
|
||||
|
||||
```text
|
||||
Main thread ends.
|
||||
Daemon thread running...
|
||||
Daemon thread running...
|
||||
...
|
||||
```
|
||||
|
||||
The program exits only after the thread completes its work.
|
||||
|
||||
---
|
||||
|
||||
### Question 3: What are some real-life use cases of daemon threads?
|
||||
|
||||
Daemon threads are commonly used for background services, such as:
|
||||
|
||||
* Garbage collection.
|
||||
* Monitoring system resources.
|
||||
* Periodic cleanup tasks.
|
||||
* Cache maintenance.
|
||||
* Logging services.
|
||||
* Background status reporting.
|
||||
|
||||
These tasks are supportive and should not keep the application alive when all user threads have finished.
|
||||
|
||||
---
|
||||
|
||||
## 3. A Shorter Way to Create Threads
|
||||
|
||||
### Question 1: What output do you get from the program?
|
||||
|
||||
Output:
|
||||
|
||||
```text
|
||||
Thread is running using a ...!
|
||||
```
|
||||
|
||||
The message is printed by the newly created thread after `thread.start()` is called.
|
||||
|
||||
---
|
||||
|
||||
### Question 2: What is the () -> { ... } syntax called?
|
||||
|
||||
This syntax is called a **Lambda Expression**.
|
||||
|
||||
Lambda expressions provide a concise way to implement functional interfaces such as `Runnable`.
|
||||
|
||||
---
|
||||
|
||||
### Question 3: How is this code different from creating a class that extends Thread or implements Runnable?
|
||||
|
||||
#### Extending Thread
|
||||
|
||||
```java
|
||||
class MyThread extends Thread {
|
||||
public void run() {
|
||||
System.out.println("Hello");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Requires creating a separate class.
|
||||
* Less flexible because Java does not support multiple inheritance.
|
||||
|
||||
#### Implementing Runnable
|
||||
|
||||
```java
|
||||
class MyRunnable implements Runnable {
|
||||
public void run() {
|
||||
System.out.println("Hello");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Separates the task from the thread.
|
||||
* More flexible and commonly preferred.
|
||||
|
||||
#### Using a Lambda Expression
|
||||
|
||||
```java
|
||||
Thread thread = new Thread(() -> {
|
||||
System.out.println("Hello");
|
||||
});
|
||||
```
|
||||
|
||||
* Shortest and most readable approach.
|
||||
* No need for an extra class.
|
||||
* Ideal when the task is simple and used only once.
|
||||
* Internally still provides an implementation of the `Runnable` interface.
|
||||
|
||||
Therefore, lambda expressions offer a concise and modern way to create threads while keeping the code easy to read and maintain.
|
||||
Reference in New Issue
Block a user