0Pricing
Java Academy · Pelajaran

Variabel Atomik: Pembaruan Tanpa Lock

Gunakan AtomicInteger, AtomicLong, dan AtomicReference untuk penghitung yang aman bagi thread tanpa lock.

Variabel Atomik: Pembaruan Tanpa Lock adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.

Masalah dengan Operasi Non-Atomik

Peningkatan sederhana count++ TIDAK aman untuk utas — operasi ini terdiri dari tiga langkah: membaca, menambah, dan menulis. Utas yang berjalan bersamaan dapat menyela urutan ini sehingga pembaruan hilang. Variabel atomik mengatasi hal ini tanpa 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

Dasar-Dasar AtomicInteger

AtomicInteger menyediakan operasi bilangan bulat yang dijamin atomik menggunakan instruksi CAS pada CPU — tidak diperlukan 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: Operasi CAS

compareAndSet(expected, update) memperbarui nilai secara atomik hanya jika nilai tersebut saat ini sama dengan nilai yang diharapkan. Mengembalikan true jika berhasil. Inilah fondasi semua algoritme tanpa 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 untuk Penghitung

AtomicLong adalah padanan 64-bit. Umumnya digunakan untuk pembuat urutan dan penghitung akses:

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

Penanda boolean yang aman untuk utas. Umumnya digunakan untuk inisialisasi satu kali atau sinyal penghentian:

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> menyediakan pembaruan atomik pada referensi objek. Digunakan untuk menerapkan struktur data tanpa 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

Terapkan fungsi secara atomik menggunakan perulangan percobaan ulang CAS secara internal:

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

Gabungkan nilai saat ini dengan nilai yang diberikan menggunakan suatu fungsi:

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 untuk Penghitung dengan Persaingan Tinggi

Dalam persaingan utas yang tinggi, percobaan ulang CAS pada AtomicLong dapat menurunkan performa. LongAdder menggunakan beberapa sel untuk mengurangi persaingan:

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

Larik Atomik

AtomicIntegerArray / AtomicLongArray menyediakan operasi atomik pada setiap elemen larik:

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

Kapan Menggunakan Atomik vs Lock

Gunakan variabel atomik ketika:

  • Pembaruan satu variabel diperlukan (penghitung, penanda, referensi)
  • Skenario memiliki persaingan rendah
  • Performa tanpa lock penting

Gunakan lock ketika:

  • Beberapa variabel harus diperbarui secara atomik
  • Diperlukan logika kondisional yang kompleks
  • Persaingan sangat tinggi (percobaan ulang CAS menurunkan performa)

Pemeriksaan Singkat

Apa yang dijamin oleh compareAndSet(expected, update)?

Ringkasan: Variabel Atomik

Inti pembelajaran:

  • Jenis atomik menggunakan instruksi CAS pada CPU — tanpa lock dan aman untuk utas
  • AtomicInteger/Long/Boolean/Reference untuk atomisitas satu variabel
  • compareAndSet adalah fondasi algoritme tanpa lock
  • updateAndGet/accumulateAndGet untuk pembaruan fungsional
  • LongAdder untuk skenario penghitung dengan persaingan tinggi

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Variabel Atomik: Pembaruan Tanpa Lock” gratis?

Ya — teks lengkap “Variabel Atomik: Pembaruan Tanpa Lock” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Variabel Atomik: Pembaruan Tanpa Lock”?

Gunakan AtomicInteger, AtomicLong, dan AtomicReference untuk penghitung yang aman bagi thread tanpa lock. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Java Academy?

Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Variabel Atomik: Pembaruan Tanpa Lock” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. ReentrantLock vs synchronized
  2. ReadWriteLock untuk Skenario Pembaca-Penulis
  3. Variabel Atomik: Pembaruan Tanpa Lock
  4. StampedLock dan Pembacaan Optimistis
← Kembali ke Java Academy