Files
HW-08-Basic-Multithreading/Report.md
T
2026-06-08 11:54:00 +03:30

149 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Theoretical Questions 📝
### 1. `start()` vs `run()`
```java
public class StartVsRun {
static class MyRunnable implements Runnable {
public void run() {
System.out.println("Running in: " + Thread.currentThread().getName());
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyRunnable(), "Thread-1");
System.out.println("Calling run()");
t1.run();
Thread.sleep(100);
Thread t2 = new Thread(new MyRunnable(), "Thread-2");
System.out.println("Calling start()");
t2.start();
}
}
```
---
❓ What output do you get from the program? Why?
✅ Answer:
The program first prints:
```
Calling run()
Running in: main
```
then it waits for 100ms (`Thread.sleep(100);`)<br>
then it prints:
```
Calling start()
Running in: Thread-2
```
When t1.run() is called, it does not create a new thread. It just executes the run() method like a normal method inside the main thread. That is why the thread name is main.
When t2.start() is called, Java creates a new separate thread, and then that new thread executes the run() method. That is why the thread name is Thread-2.
❓ Whats the difference in behavior between calling `start()` and `run()`?
✅ Answer:
Calling run() directly only runs the code in the current thread, like a normal method call.
Calling start() creates a new thread and then runs the run() method inside that new thread. So start() enables true multithreading, but run() does not.
---
### 2. Daemon Threads
```java
public class DaemonExample {
static class DaemonRunnable implements Runnable {
public void run() {
for(int i = 0; i < 20; i++) {
System.out.println("Daemon thread running...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
//[Handling Exception...]
}
}
}
}
public static void main(String[] args) {
Thread thread = new Thread(new DaemonRunnable());
thread.setDaemon(true);
thread.start();
System.out.println("Main thread ends.");
}
}
```
❓ What output do you get from the program? Why?
✅ Answer:
The output will usually be:
Main thread ends.
The daemon thread may print "Daemon thread running..." zero or a few times, but it is not guaranteed to finish. This happens because daemon threads do not keep the JVM alive. When the main thread ends and there are no user threads left, the JVM can terminate immediately.
❓ What happens if you remove `thread.setDaemon(true)`?
✅ Answer:
If thread.setDaemon(true) is removed, the thread becomes a normal user thread.
In that case, the JVM will wait for it to finish. So the program will keep running until the loop finishes, and "Daemon thread running..." will be printed 20 times.
❓ What are some real-life use cases of daemon threads?
✅ Answer:
Daemon threads are useful for background tasks that should not prevent the program from exiting.
Some examples are garbage collection, background monitoring, auto-saving, logging services, cache cleanup, and background resource management.
---
### 3. A shorter way to create threads
```java
public class ThreadDemo {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("Thread is running using a ...!");
});
thread.start();
}
}
```
❓ What output do you get from the program?
✅ Answer:
The output is:
Thread is running using a ...!
❓ What is the `() -> { ... }` syntax called?
✅ Answer:
The `() -> { ... }` syntax is called a lambda expression.
❓ How is this code different from creating a class that extends `Thread` or implements `Runnable`?
✅ Answer:
This code uses a lambda expression to provide the implementation of the Runnable interface directly.
It is shorter and cleaner than creating a separate class that extends Thread or implements Runnable. It is useful when the thread task is simple and only needed once.