# 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.