Lab 4 - Introduction to Java Multithreading
Unlike the C language, where implementing a thread and synchronization mechanisms depends on a library specific to a particular operating system (Linux, Windows, MacOSX), Java provides built-in support for working with threads directly within its SDK.
๐๏ธ Threads in Java
Implementing a New Thread
๐๏ธ The "synchronized" Keyword
The reserved keyword synchronized is used to define blocks of code and methods that represent critical sections/regions.
๐๏ธ CyclicBarrier Class
A cyclic barrier is a mechanism for (re)synchronizing multiple threads, designed to block a specified number of threads and only allow them to proceed synchronously after all of them have invoked its resynchronization method. In Java, this mechanism is represented by the CyclicBarrier class. Upon instantiation, the number of threads to be resynchronized is specified. This thread synchronization mechanism is useful for parallelized iterative algorithms that require a synchronization step for threads before moving on to the next iteration of computation. It's important to note that invoking the await() method on the cyclic barrier can throw exceptions such as BrokenBarrierException or InterruptedException.
๐๏ธ The "volatile" Keyword
The volatile keyword associated with a specific variable indicates that this variable cannot be optimized (placed in a register or excluded from conditions based on compile-time invariants). Every read or write operation associated with this variable will work directly with the RAM memory. This is useful in preventing incompatible optimizations when combined with modifying the value from another thread or reading outdated data from the core's register associated with the thread when the variable has received a new value from another thread.
๐๏ธ Atomic Variables
In laboratory session 2, we observed that the increment operation (as demonstrated with the statement a+=2) is not an atomic operation (an operation that cannot be divided when executed by a thread). Java provides support for various data types (atomic types) that come with associated atomic operations (more details here and here). These are useful for use as counters or accumulators without the need for synchronization mechanisms.
๐๏ธ Exercises
1. Create a program that launches a number of threads equal to the number of cores available on your computer. Each thread should print a text like "Hello from thread #id" to the console.