Threads & Runnable
Java-র মূল concurrency primitive — Thread ও Runnable
1. What Is a Thread?
A thread is an independent path of execution inside one process. Your Java program always has at least one —
the main thread — that starts when main is called. You can spawn more threads
to do work in parallel: downloading files, serving HTTP requests, running background tasks. When they all
finish, the JVM exits.
main call হলে শুরু হয়। সমান্তরালে কাজ করতে আরো thread বানানো যায় — download, HTTP, background task। সব thread শেষ হলে JVM বন্ধ হয়।
2. Two Ways to Start a Thread
There are two basic ways: extend Thread, or pass a Runnable (a lambda) to a new
Thread. The second is always preferred — composition over inheritance.
Thread extend করা, অথবা একটি Runnable (lambda) নতুন Thread-এ পাস করা। দ্বিতীয়টাই সবসময় ভালো — inheritance-এর বদলে composition।
class Main {
public static void main(String[] args) throws Exception {
Runnable task = () -> {
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName()
+ " - tick " + i);
}
};
Thread t1 = new Thread(task, "worker-1");
Thread t2 = new Thread(task, "worker-2");
t1.start();
t2.start();
// wait for them to finish before main exits
t1.join();
t2.join();
System.out.println("main done");
}
}
3. start() vs run() — The Classic Bug
thread.start() spawns a new OS thread and runs your code on it.
thread.run() calls the method directly on the current thread — no concurrency at all. It is
one of the most common beginner bugs in Java.
thread.start() নতুন OS thread তৈরি করে সেখানে আপনার কোড চালায়। thread.run() current thread-এই method call করে — concurrency থাকে না। এটা Java-র একটি classic beginner bug।
start আলাদা thread বানায়; run বানায় না।
4. join() — Waiting for a Thread to Finish
If your main thread finishes before its workers, the JVM may shut down half-way through. join()
blocks until the target thread completes. For a set of workers, loop and join each one.
join() ব্যবহার করুন। এটা target thread শেষ না হওয়া পর্যন্ত অপেক্ষা করে।
class Main {
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> {
try { Thread.sleep(50); } catch (InterruptedException e) {}
System.out.println("worker finished");
});
t.start();
System.out.println("main waiting...");
t.join(); // block until worker is done
System.out.println("main after join");
}
}
5. Interrupting a Thread
You cannot kill a thread in Java — you can only politely ask it to stop via interrupt().
A well-behaved thread checks Thread.currentThread().isInterrupted() periodically and also
catches InterruptedException from sleep / wait. Never swallow the
exception silently.
interrupt() দিয়ে politely অনুরোধ। ভালো thread নিয়মিত isInterrupted() check করে এবং sleep/wait-এর InterruptedException handle করে। exception কখনো silently swallow করবেন না।
class Main {
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("...working");
try {
Thread.sleep(30);
} catch (InterruptedException e) {
System.out.println("got interrupt — exiting");
Thread.currentThread().interrupt(); // preserve flag
return;
}
}
});
t.start();
Thread.sleep(100);
t.interrupt();
t.join();
System.out.println("done");
}
}
6. Daemon Threads
A daemon thread runs in the background and does not block JVM exit. Garbage collection, JIT
compilation, and timer threads are typically daemons. Mark a thread daemon before starting it with
t.setDaemon(true).
t.setDaemon(true) দিয়ে mark করুন।
| State | Meaning | বাংলায় |
|---|---|---|
| NEW | created but not started | তৈরি হয়েছে, শুরু হয়নি |
| RUNNABLE | running or ready to run | চলছে বা চলতে প্রস্তুত |
| BLOCKED | waiting for a monitor lock | lock-এর জন্য অপেক্ষা |
| WAITING | waiting indefinitely (join, wait) | অনির্দিষ্ট অপেক্ষা |
| TIMED_WAITING | waiting with timeout (sleep, wait(ms)) | timeout-সহ অপেক্ষা |
| TERMINATED | finished | শেষ হয়ে গেছে |
7. Vocabulary
| Term | Meaning | বাংলায় |
|---|---|---|
| Thread | Independent path of execution. | স্বাধীন execution path। |
| Runnable | Functional interface — a task with no return value. | functional interface — return-less task। |
| start() | Launches a new OS thread; invokes run() there. | নতুন OS thread শুরু করে। |
| join() | Blocks until target thread finishes. | target thread শেষ হওয়া পর্যন্ত অপেক্ষা। |
| interrupt() | Polite request to stop. | থামার polite অনুরোধ। |
| Daemon | Background thread that does not block JVM exit. | background thread — JVM exit block করে না। |
8. Practice Problems
-
Start two threads that each print their name three times; wait for both to finish.দুটি thread চালান যারা নিজ নিজ নাম তিনবার print করবে; দুটিই শেষ হওয়া পর্যন্ত অপেক্ষা করুন।
Show Answer (উত্তর দেখুন)
Main.javaclass Main { public static void main(String[] args) throws Exception { Runnable r = () -> { for (int i = 0; i < 3; i++) System.out.println(Thread.currentThread().getName()); }; Thread a = new Thread(r, "A"); Thread b = new Thread(r, "B"); a.start(); b.start(); a.join(); b.join(); System.out.println("main done"); } } -
Explain in 2 sentences the difference between
t.start()andt.run().দুই বাক্যে পার্থক্য ব্যাখ্যা করুন —t.start()বনামt.run()।Show Answer (উত্তর দেখুন)
Answer:
start()asks the JVM to create a brand-new OS thread and invokerun()on that new thread, so the caller returns immediately.run()is just a regular method call on the current thread — no new thread exists and the caller waits for it to return, so you get zero parallelism.start()JVM-কে বলে নতুন OS thread বানাতে এবং সেখানেrun()চালাতে — তাই caller সাথে সাথে return করে।run()current thread-এই সাধারণ method call — নতুন thread তৈরি হয় না, caller অপেক্ষা করে। -
Launch a worker that increments a counter 1000 times and prints the final value.একটি worker চালান যা counter ১০০০ বার বাড়িয়ে শেষ মান print করবে।
Show Answer (উত্তর দেখুন)
Main.javaclass Main { static int counter = 0; public static void main(String[] args) throws Exception { Thread t = new Thread(() -> { for (int i = 0; i < 1000; i++) counter++; }); t.start(); t.join(); System.out.println("counter = " + counter); } } -
Interrupt a sleeping thread and print the exception class.একটি ঘুমন্ত thread-কে interrupt করে exception-এর class print করুন।
Show Answer (উত্তর দেখুন)
Main.javaclass Main { public static void main(String[] args) throws Exception { Thread t = new Thread(() -> { try { Thread.sleep(10000); } catch (Exception e) { System.out.println("caught " + e.getClass().getSimpleName()); } }); t.start(); Thread.sleep(30); t.interrupt(); t.join(); } } -
In 3 sentences, explain why you cannot simply "kill" a thread in modern Java.তিন বাক্যে বলুন — আধুনিক Java-তে thread কেন "kill" করা যায় না।
Show Answer (উত্তর দেখুন)
Answer: The old
Thread.stop()method existed but was deprecated because abruptly killing a thread left shared data in a broken, half-updated state with locks held mid-transaction. Cooperative cancellation viainterrupt()gives the thread a chance to finish a unit of work, release locks, and clean up. It is slower to stop a thread but prevents the far worse problem of corrupted program state.পুরনো
Thread.stop()থাকলেও deprecated — হঠাৎ kill করলে shared data অর্ধ-আপডেট অবস্থায়, lock ধরা অবস্থায় থাকতে পারে।interrupt()-এর cooperative cancellation thread-কে কাজ শেষ করতে, lock ছাড়তে, cleanup করতে সুযোগ দেয়। থামতে সামান্য সময় বেশি লাগে, কিন্তু corrupted state এড়ায়।
Summary — Module 37
A thread is an independent execution path within a process. Create one by passing a Runnable
lambda to new Thread(...) and calling start() — never run(). Use
join() to wait for completion, interrupt() to politely cancel, and
setDaemon(true) for background work. Threads give you parallelism; the next modules show how
to share data among them safely.
Runnable lambda পাস করে new Thread(...), তারপর start() — কখনো run() নয়। join() অপেক্ষা, interrupt() বাতিল, setDaemon(true) background। পরবর্তী module-এ thread-এর মধ্যে নিরাপদে data share করা।