Java Academy · पाठ

Atomic Variables: Lock-Free Updates

बिना locks के thread-safe counters के लिए AtomicInteger, AtomicLong और AtomicReference का उपयोग करें।

पाठ 3, कुल 4 में से13 चरण

Atomic Variables: Lock-Free Updates, CoddyKit पर Java Academy का एक निःशुल्क पाठ है। यह 4 में से 3वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह Java Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Java Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

गैर-एटॉमिक क्रियाओं की समस्या

सरल वृद्धि count++ थ्रेड-सुरक्षित नहीं है — इसमें तीन क्रियाएँ होती हैं: पढ़ना, add, लिखना। समकालिक थ्रेड इनके बीच क्रम बदल सकते हैं, जिससे अपडेट खो जाते हैं। एटॉमिक चर बिना lock के इस समस्या का समाधान करते हैं।

// UNSAFE:
int count = 0;
// Thread A reads count=0, Thread B reads count=0
// Both write 1 — second update lost!
count++; // NOT thread-safe

// SAFE:
import java.util.concurrent.atomic.*;
AtomicInteger atomicCount = new AtomicInteger(0);
atomicCount.incrementAndGet(); // atomic, lock-free

AtomicInteger की मूल बातें

AtomicInteger CPU के compare-and-swap (CAS) निर्देशों का उपयोग करके ऐसी पूर्णांक क्रियाएँ प्रदान करता है जिनके एटॉमिक होने की गारंटी होती है — किसी lock की आवश्यकता नहीं होती।

AtomicInteger counter = new AtomicInteger(0);

counter.set(10);                   // set to 10
System.out.println(counter.get()); // 10

int prev = counter.getAndIncrement(); // returns 10, sets to 11
int curr = counter.incrementAndGet(); // sets to 12, returns 12
counter.addAndGet(5);                 // adds 5, returns 17
counter.decrementAndGet();            // subtracts 1, returns 16

compareAndSet: CAS क्रिया

compareAndSet(expected, update) मान को तभी एटॉमिक रूप से अपडेट करता है, जब वर्तमान मान expected के बराबर हो। सफल होने पर true लौटाता है। यही सभी lock-मुक्त एल्गोरिदम का आधार है।

AtomicInteger ai = new AtomicInteger(5);

boolean updated = ai.compareAndSet(5, 10); // current==5? set to 10
System.out.println(updated); // true
System.out.println(ai.get()); // 10

boolean failed = ai.compareAndSet(5, 20); // current==10, not 5 → fails
System.out.println(failed); // false
System.out.println(ai.get()); // still 10

काउंटर के लिए AtomicLong

AtomicLong 64-बिट समतुल्य है। इसका उपयोग अक्सर क्रम जनरेटर और हिट काउंटर के लिए किया जाता है:

AtomicLong seq = new AtomicLong(0);

// Thread-safe sequence generator:
long nextId() {
    return seq.incrementAndGet();
}

System.out.println(nextId()); // 1
System.out.println(nextId()); // 2
System.out.println(nextId()); // 3

AtomicBoolean

थ्रेड-सुरक्षित बूलियन फ़्लैग। इसका उपयोग आम तौर पर एक बार के आरंभीकरण या बंद करने के संकेतों के लिए किया जाता है:

AtomicBoolean initialized = new AtomicBoolean(false);

void initOnce() {
    // compareAndSet: only first caller succeeds
    if (initialized.compareAndSet(false, true)) {
        System.out.println("Initializing...");
        // perform expensive init
    } else {
        System.out.println("Already initialized");
    }
}

AtomicReference

AtomicReference<V> किसी ऑब्जेक्ट संदर्भ के लिए एटॉमिक अपडेट प्रदान करता है। इसका उपयोग lock-मुक्त डेटा संरचनाएँ लागू करने के लिए किया जाता है:

import java.util.concurrent.atomic.*;

record Config(String host, int port) {}

AtomicReference<Config> configRef =
    new AtomicReference<>(new Config("localhost", 8080));

// Hot-swap the configuration atomically:
Config oldConfig = configRef.get();
Config newConfig = new Config("prod.example.com", 443);

boolean swapped = configRef.compareAndSet(oldConfig, newConfig);
System.out.println(swapped); // true
System.out.println(configRef.get()); // Config[host=prod.example.com, port=443]

updateAndGet / getAndUpdate

आंतरिक रूप से CAS पुनःप्रयास लूप का उपयोग करके किसी फ़ंक्शन को एटॉमिक रूप से लागू करें:

AtomicInteger value = new AtomicInteger(10);

// Apply function atomically: square the value
int newVal = value.updateAndGet(x -> x * x);
System.out.println(newVal); // 100

// Get old, then apply:
int old = value.getAndUpdate(x -> x + 1);
System.out.println(old);   // 100
System.out.println(value.get()); // 101

accumulateAndGet

किसी फ़ंक्शन का उपयोग करके वर्तमान मान को दिए गए मान के साथ मिलाएँ:

AtomicInteger max = new AtomicInteger(0);

// Keep running maximum:
max.accumulateAndGet(42, Math::max); // max(0, 42) = 42
max.accumulateAndGet(15, Math::max); // max(42, 15) = 42
max.accumulateAndGet(99, Math::max); // max(42, 99) = 99

System.out.println(max.get()); // 99

अधिक प्रतिस्पर्धा वाले काउंटर के लिए LongAdder

थ्रेड की अधिक प्रतिस्पर्धा में AtomicLong के CAS पुनःप्रयास प्रदर्शन को प्रभावित कर सकते हैं। LongAdder प्रतिस्पर्धा कम करने के लिए कई सेल का उपयोग करता है:

import java.util.concurrent.atomic.*;

LongAdder adder = new LongAdder();

// Multiple threads can call add() with minimal contention:
adder.increment();
adder.add(5);
adder.increment();

System.out.println(adder.sum()); // 7
// Note: sum() is NOT atomic with add() — use only when no concurrent adds

एटॉमिक एरे

AtomicIntegerArray / AtomicLongArray अलग-अलग एरे तत्वों पर एटॉमिक क्रियाएँ प्रदान करते हैं:

AtomicIntegerArray arr = new AtomicIntegerArray(5);

arr.set(0, 10);
arr.incrementAndGet(0);
arr.compareAndSet(2, 0, 42); // index 2: if 0, set 42

System.out.println(arr.get(0)); // 11
System.out.println(arr.get(2)); // 42

एटॉमिक चर बनाम lock का उपयोग कब करें

एटॉमिक चर का उपयोग करें, जब:

  • एकल चर के अपडेट हों (Counter, फ़्लैग और संदर्भ)
  • कम प्रतिस्पर्धा वाली स्थितियाँ हों
  • lock-मुक्त प्रदर्शन महत्वपूर्ण हो

lock का उपयोग करें, जब:

  • कई चर को एटॉमिक रूप से अपडेट करना हो
  • जटिल सशर्त तर्क की आवश्यकता हो
  • बहुत अधिक प्रतिस्पर्धा हो (CAS पुनःप्रयास प्रदर्शन को प्रभावित करते हों)

त्वरित जाँच

compareAndSet(expected, update) क्या गारंटी देता है?

पुनरावलोकन: एटॉमिक चर

मुख्य बातें:

  • एटॉमिक प्रकार CPU के CAS निर्देशों का उपयोग करते हैं — lock-मुक्त और थ्रेड-सुरक्षित
  • एकल चर की एटॉमिकता के लिए AtomicInteger/Long/Boolean/Reference
  • compareAndSet lock-मुक्त एल्गोरिदम का आधार है
  • फ़ंक्शनल अपडेट के लिए updateAndGet/accumulateAndGet
  • अधिक प्रतिस्पर्धा वाले काउंटर परिदृश्यों के लिए LongAdder
शुरुआत निःशुल्क

एआई शिक्षक के साथ Java सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
104
पाठ
374

अक्सर पूछे जाने वाले प्रश्न

क्या “Atomic Variables: Lock-Free Updates” पाठ निःशुल्क है?

हाँ—“Atomic Variables: Lock-Free Updates” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और Java Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। Java Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“Atomic Variables: Lock-Free Updates” में मैं क्या सीखूँगा?

बिना locks के thread-safe counters के लिए AtomicInteger, AtomicLong और AtomicReference का उपयोग करें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Java Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या Java Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Java Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 3वाँ पाठ है।

“Atomic Variables: Lock-Free Updates” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस Java Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर Java Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. ReentrantLock बनाम synchronized
  2. Reader-Writer Scenarios के लिए ReadWriteLock
  3. Atomic Variables: Lock-Free Updates
  4. StampedLock और Optimistic Reads
← Java Academy पर वापस जाएँ