## Question 1
An atomic variable in Computer Science refers to a basic data or input variable that is used to build performance variables. These variables are not summaries or ratios, but rather fundamental building blocks in operational systems.

Atomic variables allow multiple threads to safely read and update a shared value without using explicit locks, guaranteeing that operations like increment-and-update happen as a single, uninterruptible step. Ordinary variables don't provide this guarantee—if multiple threads modify them concurrently, updates can be lost due to race conditions.

## Question 2
`AtomicInteger`

`AtomicLong`

`AtomicBoolean`

`AtomicReference<T>` for any type of object.

## Question 3
| | Locks (`synchronized`/`ReentrantLock`) | Atomic Variables |
|---|---|---|
| Mechanism | Blocking (mutual exclusion) | Lock-free |
| Scope | Can protect multiple statements/variables | Single variable only |
| Performance | Slower under contention | Generally faster |
| Deadlock risk | Possible | None |
| Best for | Complex critical sections | Simple counters, flags, single values |

## Question 4
A program can be completely free of race conditions yet still perform poorly, because the very mechanisms used to guarantee correctness — such as locks or CAS — introduce overhead. When many threads compete for the same shared resource, they end up **blocking or repeatedly retrying**, which sharply reduces throughput even though correctness is fully preserved.

Some concurrency-related factors that may limit scalability even when correctness iss guaranteed:

1. Lock contention
2. Context switching overhead
3. Cache coherence traffic

## Question 5
Despite the three factors given in the previous question there is a vital factor which is **limited CPU cores**.

once threads exceed available cores, they compete for the same processing units, adding scheduling overhead instead of true parallelism.

Context-switching overhead – the OS spends more time switching between threads than executing actual work.

Cache coherence traffic – shared/false-shared memory locations cause costly cross-core cache invalidation.

## Question 6
A precise timing where two or more threads each acquire one lock and then attempt to acquire the other's lock simultaneously.

1. Stress testing with high concurrency – run many more threads than in normal testing.
2. Deliberate interleaving control / thread scheduling tools – use tools or techniques that artificially manipulate thread timing to force specific interleavings, such as:
   Inserting `Thread.sleep()` or `yield()` calls strategically between lock acquisitions.