Detailed Notes on Threads & Concurrency
Background Info
- Ability to run multiple programs is thanks to the idea of Time Splicing: O/S runs each Program for a few Miliseconds before swapping them out to create the illusion of Concurrency
- Illusion is maintable thanks to increasing CPU speed thanks to the process described by Moore's Law
- Need to Eventually break down CPU into multiple cores due to increasing power consumption and heat generation caused by the more Powerful CPU
- Multiple Cores run at slower speed and power but mimic the capability of the faster single CPU core
Java Threads
- Threads can run either Sequentially(One thread going through everything) or Concurrently(Multiple threads working through together)
- Java Threads work on a Shared Memory Architecture(One Program: All threads share memory)
- Two ways to use Java Threads:
- Implement Runnable
- Extend Thread
- Three main Java Thread Methods:
- Thread.start()
- Thread.join()
- Thread.run()
Methods of Concurrency & Problems
- Two Ways to Decompose a Problem for Concurrency
- Task Decomposition
- Domain Decomposition
- Task Decomposition involves breaking down the problem into subtasks that are each managed by a Thread. Main Benefit: Responsiveness
- Domain Decomposition involves breaking down the data down into subsets for each thread to process. Main Benefit: Pure Speed
- Problem: Thread execution order is unpredictable because threads are prevented from hogging CPU to keep up illusion of Time Splicing and main thread can move on without other threads
- Solution: Thread.join()
- Thread.join() is a minor form of synchronization that blocks the main thread until the calling thread has finished its run() method
Race Condition & Synchronized
- Race Condition: Two or more threads attempt to access shared data and modify it at the same time.
- Creates an issue where data can be overwritten or certain actions are not successful
- Results vary with each execution due to the unpredictable order of threads
- Solution: Synchronization(keyword: sychronized)
- Sychronized keyword uses an object as a lock that prevents multiple threads from being inside of the synchronized block at once
- Sychronized keyword can also be used on methods, but is ideally used around specific blocks of code.
- Best case usage: Use when modifying shared data such as static variables/data structures