From 2efd5e3e350bd98b7e464b2247b2f0f18897f705 Mon Sep 17 00:00:00 2001 From: Farnam Jahangard Date: Wed, 10 Jun 2026 17:33:46 +0330 Subject: [PATCH] answered theoretical questions finished the bonus task in theoretical questions part --- ANSWERS.md | 54 +++++++++++++++++++++++++ src/main/java/bonus/AtomicVsNormal.java | 42 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 ANSWERS.md create mode 100644 src/main/java/bonus/AtomicVsNormal.java diff --git a/ANSWERS.md b/ANSWERS.md new file mode 100644 index 0000000..97301d5 --- /dev/null +++ b/ANSWERS.md @@ -0,0 +1,54 @@ +# Answers + +## Q1 +Atomic variable is a type of variable that combines all three process of: read, write and update into a single operation. +as an example when we write `i++` it may seem like a single operation +but the compiler needs to read `i`(read), add 1 to it (update) and change `i` to new value (write) +since all these operations are combined into one operation race conditions doesn't occur +unlike normal variables. + +## Q2 +`AtomicInteeger`, `AtomicBoolean`.`AtomicLong` & `AtomicReference` + +#### `AtomicInteeger` Use case +used as counters that are shared across threads +#### `AtomicBoolean` Use case +used as flags that are used across threads (like `running` flag) +#### `AtomicLong` Use case +in general anything that needs long operations for multiple threads such as a bank account balance or an id counter +#### `AtomicReference` Use case +it's used whenever you need atomic operations on any object + +## Q3 +locks are used to lock a full block of code, this prevents race conditions as a thread locks the section it's working on when it reaches it + +therefore we should use locks when we wan't to prevent race conditions for a block of code +and use atomic variables on more basic things +## Q4 +this situation may occur because if there are too many threads trying to access a shared resource performance drops because workers sleep more than they do work + +#### Usage of locks +locks make a block of code completely unaccessible for every thread except one +this would cause those other threads to sleep meaning even if you have 100 threads only one of them can work at a time. + +#### Usage of atomic variables +when we use atomic variables and atomic operations, at a curtain point many threads my try to change one variable +only one can successfully access the variable, meaning the rest would fail +this failure is just waste of cpu power. + +## Q5 +majority of mainstream cpus has something around 8 to 16 cores right now +this means one thing +logically we can't run 100 threads at the same time in parallel +this causes something known as context switching: cpu cores need to switch between threads +and this continuous switching would make the program slow + + +cpu cores have their own distinct cache, when a core changes a synced variable all the cpu cores change their cache value of that variable +when we have too many threads working on a synced variable, cpu cores constantly follow the changes in order to keep their cache synced +this would cause cpu cores to spend more time synchronizing the cache rather than processing the threads +this situation is known cache coherence synchronization overhead. + +## Q6 +Deadlocks are rare because you can't determine threads execution order, OS determines this by itself +to increase likelihood of deadlocks to happen a developer can start too many threads and delay the threads \ No newline at end of file diff --git a/src/main/java/bonus/AtomicVsNormal.java b/src/main/java/bonus/AtomicVsNormal.java new file mode 100644 index 0000000..8a5aa08 --- /dev/null +++ b/src/main/java/bonus/AtomicVsNormal.java @@ -0,0 +1,42 @@ +package bonus; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +public class AtomicVsNormal { + private static int counter = 0; + private static AtomicInteger atomicCounter = new AtomicInteger(0); + + public static void main(String[] args){ + int incrementCount = 1000; + List workers = new ArrayList<>(); + + for (int i = 0; i < 10; i++){ + workers.add(new Thread(() ->{ + for (int j = 0; j < incrementCount; j++) { + counter++; + atomicCounter.incrementAndGet(); + } + } + )); + } + + for (Thread worker : workers){ + worker.start(); + } + + for (Thread worker : workers){ + try { + worker.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + System.out.println("Expected: 10000"); + System.out.println("Normal increment: " + counter); + System.out.println("Atomic increment: " + atomicCounter.get()); + + } +}