What’s a Thread?
A thread is the smallest unit of execution in a process
A process is a program in execution
A single process can have multiple threads which share the same memory space
Analogy
A process is cooking and then threads are the tasks associated with cooking like chopping vegetables, boiling water e.t.c
Multiple threads can happen at the same time making the process faster and more efficient
Differences Between A Thread and A Process.
Aspect | Process | Thread |
Definition | a program in execution | the smalles t unit of execution within a process |
Memory | utilises it’s own memory space | threads of the same process utilise the same memory space |
Creation | Heavyweight - requires a lot of resources | Lightweight - requires less resources |
Communication | Inter-process communication is slower | Inter-thread communication is faster |
Dependency | Processes are independent of each other | Threads of the same process are dependent of each other, failure of one affects the rest. |
Creating Threads in Java
Extending Thread Class
Create a new class that extends the Thread class and override the run() method.
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running!");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // Starts the thread
}
}
Implementing the Runnable Interface
Create a new class that implements the Runnable Interface and pass it to a Thread object.
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread is running!");
}
}
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start(); // Starts the thread
}
}
Why Use Runnable Over Thread Class?
Java doesn’t support multi-inheritance, so if you’ve already another class it won’t allow you to extend the Thread class.
Runnable is more flexible and supports the “Composition over Inheritance” Principle.
What’s the “Composition Over Inheritance” Principle?
Composition over inheritance is a design principle that suggests favoring composition (using objects of other classes as members) over inheritance (extending a class) to achieve code reuse and flexibility.
Why it’s important:
Inheritance can lead to tightly coupled code, making it harder to maintain and extend.
Composition allows for more flexible and modular designs.
Thread LifeCycle
New: thread has been creates but not yet started.
Runnable: the thread is up and running.
Blocked/Waiting: The thread is waiting for for a resource or another thread to finish.
Timed Waiting: the thread is waiting for a specific amount of time.
Terminated: the thread has finished it’s execution.
Threads go through a lifecycle: New → Runnable → Blocked/Waiting → Terminated.
Starting and Running Threads (start()
vs run()
)
start ()
It starts the thread and calls the run method
The JVM calls a new thread of execution.
run ()
calls the run() method on the current thread; executes the code in the current method.
No new thread is created,
Daemon threads
A daemon thread is a background thread that supports user threads e.g. garbage clollection.
It automaticallly terminates when all user threads finish execution.
FAQs
What happens when you call the run() before the start() ?
The run() method will execute the run() in the current thread which in this case would most probably be the main thread.
Can you change a thread to a daemon thread after it has started? Why or why not?
No, you cannot change a thread to a daemon thread after it has started.
Why?:
- The
setDaemon()
method must be called before the thread is started. If you try to call it after starting the thread, it will throw anIllegalThreadStateException
.
- The
What’s garbage collection in this context?
It’s is an automatic process that reclaims memory by destroying unused objects.