Files

4.0 KiB
Raw Permalink Blame History

Theoretical Questions

1. start() vs run()

Question 1: What output do you get from the program? Why?

output:

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: Whats 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:

Main thread ends.

Or a few lines such as:

Daemon thread running...
Main thread ends.

Explanation:

The created thread is marked as a daemon thread using:

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:

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:

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

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

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

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.