Skip to content

Providing examples about parallelism, processes, threads, concurrency, and related topics. I will start with `Java` and soon I will add `Rust`.

License

Notifications You must be signed in to change notification settings

msskzx/parallelismessness

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Parallelismessness

Providing examples about parallelism, processes, threads, concurrency, and related topics. I started with Java, and soon I will also add C++ and Rust.

Outline

  • Thread Safety and Race Conditions
  • Services Initialization
  • Executing Threads Alternately
  • Examples on Thread Safety and Race Conditions

Thread Safety and Race Conditions

A race condition occurs when multiple threads or processes try to change shared resource simultaneously which can lead to undesirable results.

  • Counter.java has some examples on how race conditions happen and why thread safety is important.

Services Initialization

A common scenario when using multiple threads is that you need to wait for some services to initialize before proceeding. For that CountDownLatch could be used, to ensure a condition is met before proceeding.

  • InOrder.java we need certain order of execution when we are running multiple threads.

Executing Threads Alternately

One approach to execute two threads in an alternating order is to use Semaphore where each thread acquires its own semaphore and releases the semaphore for the other thread.

  • PrintAlternately.java has an example alternating between two threads.
  • ZeroEvenOdd.java has an example alternating between three threads.

Examples on Thread Safety and Race Conditions

Lock

In Counter.java a number of threads try to increment the counter, without handling race conditions, the threads read inconsistent state of the counter, so maybe both read 10 at the same time and increment it to 11. This results in wrong final value:

void incCounterWrong() {
    this.counter++;
}
Final Counter: 19762

In this example we used lock which a thread must gain before it can execute the code within that code block. If the lock is held by another thread, other threads are blocked. Handling of race condition using lock:

private final Object lock;

void incCounter() {
    synchronized (lock) {
        this.counter++;
    }
}
Final Counter: 20000

Synchronized Method

In this scenario, the whole method is synchronized. This means all synchronized methods share the same lock on the class instance level, which means that no other synchronized method is allowed to execute simultaneously:

synchronized void incCounterSync() {
    this.counter++;
}
Final Counter: 20000

Atomic Variables

AtomicInteger provides a wrapper around the int so that you can call the operation and the synchronization is handled inside without you handling it. It uses Compare-and-Swap (CAS) to ensure thread safety without using locks.

private AtomicInteger atomicCounter;
void incAtomicCounter() {
    this.atomicCounter.getAndIncrement();
}
Final Counter: 20000

About

Providing examples about parallelism, processes, threads, concurrency, and related topics. I will start with `Java` and soon I will add `Rust`.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages