Skip to content

Lesson 01 · Threads & Tasks

Objectives

After this lesson you will be able to:

  • Define tasks with Runnable and Callable and run them on a Thread.
  • Trace a thread's lifecycle states.
  • Retrieve a result (or exception) from a Future.

Runnable vs Callable

Both model a task; the difference is the return value and exceptions:

RunnableCallable<V>
Methodvoid run()V call() throws Exception
Returnsnothinga value V
Checked exceptionsnoyes
java
Runnable r = () -> System.out.println("work");
Callable<Integer> c = () -> 6 * 7;          // returns 42, may throw

Starting a thread

new Thread(runnable).start() runs the task on a new thread. Calling run() directly does not start a thread — it executes on the current one.

java
Thread t = new Thread(r);
t.start();        // spawns a new thread, then returns immediately
t.join();         // wait for t to finish

Exam trap

start() launches a new thread; run() does not — it's a plain method call on the current thread. Calling start() twice on the same Thread throws IllegalThreadStateException.

Thread lifecycle

A thread moves through Thread.State values:

NEW → RUNNABLE → (BLOCKED | WAITING | TIMED_WAITING) → RUNNABLE → TERMINATED
  • NEW — created, not started.
  • RUNNABLE — eligible to run (running or ready).
  • BLOCKED — waiting for a monitor lock.
  • WAITING / TIMED_WAITINGwait(), join(), sleep(ms).
  • TERMINATED — finished.

Future

Submitting a Callable/Runnable to an executor returns a Future — a handle to a result that may not exist yet.

java
ExecutorService ex = Executors.newSingleThreadExecutor();
Future<Integer> f = ex.submit(() -> 6 * 7);
Integer answer = f.get();        // blocks until done → 42
ex.shutdown();

Gotcha

future.get() blocks until the task completes and rethrows any task exception wrapped in ExecutionException (use getCause() for the original). get(timeout, unit) throws TimeoutException if it isn't ready in time.

Key Takeaways

  • Runnable (void run(), no checked exceptions) vs Callable<V> (V call() throws Exception, returns a value).
  • start() spawns a new thread; run() doesn't. A second start() throws IllegalThreadStateException.
  • States: NEW → RUNNABLE → (BLOCKED/WAITING/TIMED_WAITING) → TERMINATED; join() waits for completion.
  • A Future holds a pending result; get() blocks and wraps task exceptions in ExecutionException.

Lesson Quiz

Lesson Quiz · Threads & Tasks0 / 4
  1. What's the difference between calling start() and run() on a Thread?

    • ANothing
    • Bstart() spawns a new thread; run() executes on the current thread
    • Crun() spawns a new thread
    • Dstart() is deprecated
  2. Which can return a value and throw a checked exception?

    • ARunnable
    • BCallable
    • CThread
    • DFuture
  3. What happens if you call start() twice on one Thread?

    • ARuns twice
    • BIllegalThreadStateException
    • CNothing the second time
    • DInterruptedException
  4. A task throws inside a Callable. What does future.get() do?

    • AReturns null
    • BThrows the original exception directly
    • CThrows ExecutionException wrapping the cause
    • DHangs forever

Next: Executors & Concurrent Utilities. Run the matching code in labs/src/main/java/com/jse21/m07_concurrency/.