Concurrency in Software Architecture

Concurrency is decoupling strategy. It helps us decouple what gets done from when it get done.

Concurrency pattern is implemented to support multiple executions simultaneously to make use of all the CPU cores to complete tasks quickly and reduce wait time for every task. Process called Thread which perform multiple executions and lead to achieve concurrency pattern.

Threads share resources with each other and execute tasks quickly and efficiently.

  • Concurrency always improves performance
    • It can improve performance sometimes but only where there is a lot of wait time that can be shared between multiple threads or processors.
  • Design does not change when writing concurrency program due to decoupling butt it does varies based on single threaded system.
  • Understanding concurrency issues are not important when working with a container such as a Web or EJB container.
  • Concurrency incurs some overhead, both in performance as well as writing additional code.
  • Correct concurrency is complex, even for simple problems.
  • Concurrency often requires a fundamental change in design strategy.
Concurrency has few principles and techniques for defending systems from the problems of concurrent code as follow :
  • Single responsibility principle which is the first principle of S.O.L.I.D principles as it states method/class/component should have a single responsibility and single reason to change.
  • Limit the scope of Data so two threads will not be able to modify the same field of shared resource or object.
  • Use copies of Data to avoid shared data and make it read-only. In cases of write operations, collect results from multiple threads and merge all result in a single thread.
  • Threads should be as independent as possible to avoid data sharing.
Thread safe mechanisms are available using locking APIs provided in Java concurrency package like ReentrantLock, Semaphore or CountDownLatch and more... 

Several ways to partition behaviors in concurrent application :
  • Bound Resources : Resources of a fixed size or number used in a concurrent environment.
  • Mutual Exclusion : Only one thread can access shared data or a shared resource at a time.
  • Starvation : Once thread or a group of threads is prohibited from proceeding for an excessively long time or forever.
  • Deadlock : Two or more threads waiting on each other to finish. Each thread has a resource that the other thread requires and neither can finish until it gets the other resource.
  • Livelock : Threads in lockstep, each trying to do work but finding another "in a way". Due to resonance, threads continue trying to make progress but are unable to for an excessively long time or forever.
There are various execution models used in concurrent programming:
  • Producer-Consumer Model
  • Readers-Writers Model
  • Dining Philosophers Model
Dependencies between Synchronized Methods in Concurrency:
  • Client-Based Locking
  • Server-Based Locking
  • Adapted Server
Note: Keep Synchronized sections small as possible.

Testing Threaded Code to prove it's correctness will not be guaranteed. However good and thorough enough testing can minimize the risk. Following are the considerations :
  • Treat spurious failures as candidate threading issues.
  • Get non-threaded code working first.
  • Make threaded code pluggable.
  • Make threaded code tunable.
  • Run with more threads than processors.
  • Run on different platforms.
  • Instrument code to try and force failures.


Comments

Popular posts from this blog

System Design Interviews 2022