🔖 Introduction
In the real world, programs often need to do many things at the same time: download files, update UI, process data—all at once. This is where multithreading comes in.
In this lesson, you’ll learn how to:
- Create threads
- Use the
Runnable
interface - Understand synchronization
- Avoid common threading issues
Let’s make your programs faster and smarter 💡
🧠 What is a Thread?
A thread is a lightweight process—a separate path of execution in your program.
Multithreading is the ability to run multiple threads in parallel, improving performance and responsiveness.
🧵 1. Creating a Thread by Extending Thread
Class
class MyThread extends Thread {
public void run() {
System.out.println("Thread running: " + Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start(); // runs in a separate thread
}
}
Use start()
instead of run()
to run in parallel.
🤝 2. Creating a Thread with Runnable
Interface
class MyTask implements Runnable {
public void run() {
System.out.println("Running task: " + Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
Thread t1 = new Thread(new MyTask());
t1.start();
}
}
💡 Thread Lifecycle
- New
- Runnable
- Running
- Waiting/Blocked/Sleeping
- Terminated
😴 Thread Sleep
Make a thread pause:
Thread.sleep(1000); // 1000 ms = 1 sec
🧭 Thread Priorities
You can set thread priority using:
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
🧊 3. Synchronization – Prevent Data Corruption
When multiple threads access shared data, we must synchronize access to avoid race conditions.
❌ Problem Without Sync:
class Counter {
int count = 0;
public void increment() {
count++;
}
}
Two threads might increment the value at the same time, causing wrong results.
✅ Solution: synchronized
Keyword
class Counter {
int count = 0;
public synchronized void increment() {
count++;
}
}
Now, only one thread can access increment()
at a time.
🧪 Mini Challenge
class Printer implements Runnable {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " - Printing " + i);
}
}
}
public class Main {
public static void main(String[] args) {
Thread t1 = new Thread(new Printer());
Thread t2 = new Thread(new Printer());
t1.start();
t2.start();
}
}
Try running this and see how both threads interleave!
🛡️ Best Practices
- Use
Runnable
instead of extendingThread
(more flexible). - Always use
start()
to run threads. - Use synchronization carefully — too much can cause deadlocks.
- Consider using Executors for advanced threading.
✅ What You Learned
Best practices for safe multithreading
Creating threads using Thread
and Runnable
Thread lifecycle and methods
Synchronization to protect shared data