diff --git a/Answers.md b/Answers.md index e69de29..b4221cc 100644 --- a/Answers.md +++ b/Answers.md @@ -0,0 +1,97 @@ +## Question 1 +An **atomic variable** is a special type of variable that performs operations + +The purpose of using them is to prevent **race conditions** + +- **Atomic variables**: thread-safe for simple operations (like increment, update). + +- **Ordinary variables**: can cause race conditions if multiple threads change them together without protection. + +## Question 2 + +Examples of classes in java.util.concurrent.atomic: + +1. AtomicInteger +2. AtomicLong +3. AtomicBoolean +4. AtomicReference + +AtomicInteger: +Used as a thread-safe counter. For example, in a multithreaded server, multiple threads can increase the number of requests safely without using synchronized. + +## Question 3 + +Atomic variables: It's better for simple operations on a single value (increment, update, compare-and-set). +They are usually faster and lighter because they avoid blocking threads. + +Locks: Used when multiple operations must happen together. Threads wait until the lock is released. + + +Use a lock when: + +- Multiple variables must stay consistent together + +- A complex sequence of actions must be protected + +- You need critical sections with more control + + +Use an atomic variable when: + +- Only one variable is shared + +- Operations are simple (counter) + +- High performance and low overhead are important + + +## Question 4 + +A program can be free of race conditions but still be slow under high contention because correctness does not mean good performance. +Threads may work safely but spend time waiting instead of doing useful work. + +Three factors that limit scalability: + +1. Lock Contention + Many threads try to access the same lock. Only one can continue, so others wait, reducing parallelism. + + +2. Context Switching + The CPU constantly switches between threads. Frequent switching adds overhead and wastes time. + + +3. Synchronization Overhead + Operations like locks, atomic updates, and coordination between threads require extra CPU work and memory synchronization. + + +## Question 5 + +Adding more threads does not always improve performance because after a certain point, threads start spending more time coordinating and competing than doing actual work. + +1. When there are too many threads, the CPU frequently switches between them. +Saving and restoring thread states creates overhead and reduces efficiency. + + +2. Multiple threads may compete for the same resources (locks, memory, shared data). Some threads must wait, so parallel execution decreases. + + +3. Each CPU core has its own cache. When several threads modify shared data, caches must stay synchronized, +creating extra communication and slowing execution. + + +4. Locks, atomic operations, and coordination mechanisms require additional processing time to maintain correctness. + + +## Question 6 + +Deadlocks often appear in production but not during testing. During testing, threads may run in a favorable order and +never reach the lock sequence that causes deadlock. In production, different timing, higher load, and more threads can create the exact conditions needed. + +Two strategies to expose deadlocks during testing: + +1. Stress / Load Testing + Run the program with many threads, repeated executions, and high concurrency to increase the chance of problems. + + +2. Introduce Scheduling Variations + Add random delays, sleeps, or use concurrency testing tools to force different execution orders and increase the probability of triggering deadlocks.