Lecture from: 27.02.2024 | Video: Video ETHZ
Java Threads
Java Threads: Key Points
- Every Java program has at least one thread (the main thread).
start()
creates an actual execution thread.- A program ends when all non-daemon (= user thread, keeps running until execution finishes) threads finish.
- Threads can continue to run even if
main()
returns. - Creating a
Thread
object does not start a thread; callingrun()
directly also does not start a new thread.
Useful Thread Attributes and Methods
- ID: A unique identifier for each thread.
- Name: A string name for the thread (can be set).
- Priority: A numerical priority (1-10) that influences scheduling.
- Status: The current state of the thread (NEW, RUNNABLE, BLOCKED, etc.).
Using Thread States and Priorities
This example demonstrates setting thread priorities and monitoring thread states.
Observations: threads are often blocked due to I/O, and higher-priority threads tend to finish before lower-priority threads.
Joining Threads
A common scenario is a main thread spawning worker threads and then needing to wait for their results. Busy waiting (repeatedly checking the state of worker threads) is inefficient.
The join()
method provides a better solution. A thread calling thread.join()
will block until the thread
object terminates.
Performance Trade-off: join()
incurs context switch overhead. If worker threads are very short-lived, busy waiting might be faster (but generally, join()
is preferred).
Exceptions
In a single-threaded program, an uncaught exception terminates the program. In a multithreaded program, an exception thrown in a worker thread:
- Is usually shown on the console.
- Does not affect the behavior of
thread.join()
. - May not be noticed by the main thread.
Setting UncaughtExceptionHandler
s
The UncaughtExceptionHandler
interface allows you to handle unchecked exceptions in threads. You can register a handler:
- With a specific
Thread
object. - With a
ThreadGroup
object. - Globally for all threads using
setDefaultUncaughtExceptionHandler()
.
Shared Resources
Analogy: threads “fighting” over the console.
Synchronized Incrementing and Decrementing
This example shows two threads (one incrementing, one decrementing) a shared counter. The results are unpredictable because the increment/decrement operation (this.value += delta;
) is not atomic. It’s executed in multiple bytecode instructions.
Relevant bytecode for increment operation:
Continue here: 05 Introduction to Threads and Synchronization (Part III)