### 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? - The output is: ``` Calling run() Running in: main Calling start() Running in: Thread-2 ``` Since `t1.run()` executes the `run()` method directly inside the main thread, but `t2.start()` executes it inside the created new thread. #### What’s the difference in behavior between calling `start()` and `run()`? - Calling `run()` is just a normal method call, so the program waits for it to finish before moving to the next line. Calling `start()` tells Java to create a new thread and execute the `run()` method inside it, which allows it to run alongside the main thread. --- ### 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? - The output is: ``` Main thread ends. Daemon thread running... ``` Since `thread.setDaemon(true)` marks the thread as a background "daemon" thread, the program ends as soon as all user (non-daemon) threads (the main thread in this case) have finished, regardless of whether the daemon thread has completed its task. #### What happens if you remove `thread.setDaemon(true)`? - The program continues printing `Daemon thread running...` 20 times even after the main thread has finished. ``` Main thread ends. Daemon thread running... . . . Daemon thread running... ``` #### What are some real-life use cases of daemon threads? - In general, when we want a background task to run **only** while the main program is running, we use daemon threads. For example, background tasks like cache clearing, checking connectivity to a server, or monitoring CPU/Memory usage can all be done using daemon threads. --- ### 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? - The output is: ``` Thread is running using a ...! ``` #### What is the () -> { ... } syntax called? - It's called a lambda expression #### How is this code different from creating a class that extends Thread or implements Runnable? - It’s much shorter and easier to read. Instead of having to define a new custom thread class (by extending Thread) or separate the task from the thread itself (by implementing Runnable) just to run a few lines of code, a lambda expression lets us pass the code directly to the thread.