Java Academy · Pelajaran

ReentrantLock berbanding synchronized

Bandingkan ciri ReentrantLock (tryLock, lockInterruptibly, keadilan) dengan kata kunci synchronized.

Pelajaran 1 daripada 413 langkah

ReentrantLock berbanding synchronized ialah pelajaran Java Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Java Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Kata Kunci synchronized

Kata kunci synchronized Java menyediakan eksklusi bersama menggunakan lock intrinsik objek (monitor). Ringkas tetapi terhad — tiada had masa, keadilan atau kebolehan untuk diganggu.

class Counter {
    private int count = 0;
    
    synchronized void increment() {
        count++; // only one thread at a time
    }
    
    synchronized int get() { return count; }
}

Counter c = new Counter();
// Multiple threads can safely call increment()

Asas ReentrantLock

ReentrantLock ialah lock eksplisit daripada java.util.concurrent.locks. Ia menyediakan eksklusi bersama yang sama seperti synchronized, tetapi dengan lebih banyak kawalan. Lock mesti dilepaskan secara manual dalam blok finally.

import java.util.concurrent.locks.*;

class SafeCounter {
    private int count = 0;
    private final ReentrantLock lock = new ReentrantLock();
    
    void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock(); // always release in finally!
        }
    }
    
    int get() {
        lock.lock();
        try { return count; }
        finally { lock.unlock(); }
    }
}

tryLock: Pemerolehan Tanpa Menyekat

tryLock() cuba memperoleh lock tanpa menyekat. Mengembalikan true jika berjaya dan false jika lock dipegang oleh benang lain.

ReentrantLock lock = new ReentrantLock();

if (lock.tryLock()) {
    try {
        System.out.println("Got the lock, doing work");
    } finally {
        lock.unlock();
    }
} else {
    System.out.println("Lock busy, skipping or retrying");
}

tryLock dengan Had Masa

Tunggu sehingga tempoh yang ditetapkan untuk memperoleh lock:

try {
    if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
        try {
            // work with protected resource
            System.out.println("Acquired within 500ms");
        } finally {
            lock.unlock();
        }
    } else {
        System.out.println("Timed out waiting for lock");
    }
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}

lockInterruptibly

lockInterruptibly() memperoleh lock kecuali benang diganggu — berguna untuk tugas yang boleh dibatalkan dan sedang menunggu lock:

try {
    lock.lockInterruptibly(); // throws InterruptedException if interrupted
    try {
        // do work
    } finally {
        lock.unlock();
    }
} catch (InterruptedException e) {
    System.out.println("Interrupted while waiting for lock");
    Thread.currentThread().interrupt();
}

Kemasukan Semula

Kedua-dua synchronized dan ReentrantLock menyokong kemasukan semula — benang yang sudah memegang lock boleh memperolehnya sekali lagi tanpa menyebabkan kebuntuan:

synchronized void outer() {
    System.out.println("outer");
    inner(); // same thread re-enters — OK
}

synchronized void inner() {
    System.out.println("inner"); // same lock, same thread
}

// ReentrantLock:
ReentrantLock lock = new ReentrantLock();
lock.lock();
lock.lock(); // acquire again — hold count = 2
lock.unlock(); // hold count = 1
lock.unlock(); // hold count = 0, lock released

Dasar Keadilan

Cipta ReentrantLock yang adil untuk memberikan akses mengikut susunan FIFO — menghalang kebuluran benang dengan mengorbankan daya pemprosesan yang lebih rendah:

// Unfair (default): no ordering guarantee, better throughput
ReentrantLock unfair = new ReentrantLock();

// Fair: threads acquire in arrival order
ReentrantLock fair = new ReentrantLock(true);

System.out.println(fair.isFair()); // true

Pemboleh Ubah Condition

ReentrantLock menyediakan objek Condition — lebih fleksibel daripada wait()/notify():

ReentrantLock lock2 = new ReentrantLock();
Condition notEmpty = lock2.newCondition();
Queue<String> queue = new LinkedList<>();

// Producer
lock2.lock();
try {
    queue.offer("item");
    notEmpty.signal(); // wake one waiting thread
} finally { lock2.unlock(); }

// Consumer
lock2.lock();
try {
    while (queue.isEmpty()) notEmpty.await(); // wait & release lock
    System.out.println(queue.poll());
} finally { lock2.unlock(); }

Bila Hendak Menggunakan ReentrantLock berbanding synchronized

Gunakan synchronized apabila:

  • Eksklusi bersama yang ringkas diperlukan
  • Tiada had masa, keadilan atau kebolehan untuk diganggu diperlukan

Gunakan ReentrantLock apabila:

  • tryLock() atau tryLock(timeout) diperlukan
  • lockInterruptibly() diperlukan
  • Susunan yang adil diperlukan
  • Berbilang pemboleh ubah Condition diperlukan

Kiraan Lock dan Pemantauan

ReentrantLock menyediakan kaedah diagnostik:

ReentrantLock lock3 = new ReentrantLock();
lock3.lock();
lock3.lock(); // reentrant — hold count 2

System.out.println(lock3.getHoldCount());    // 2
System.out.println(lock3.isHeldByCurrentThread()); // true
System.out.println(lock3.isLocked());        // true
System.out.println(lock3.getQueueLength());  // 0 (no waiting threads)

lock3.unlock();
lock3.unlock(); // fully released

Kesilapan Lazim: unlock Tanpa lock

Memanggil unlock() apabila benang semasa tidak memegang lock akan melontarkan IllegalMonitorStateException. Sentiasa pasangkan lock dengan unlock atau gunakan try-finally:

ReentrantLock lock4 = new ReentrantLock();
try {
    // If lock() is never called (e.g., skipped by exception before this line)
    lock4.unlock(); // throws IllegalMonitorStateException
} catch (IllegalMonitorStateException e) {
    System.out.println("Must lock before unlock!");
}

Semakan Pantas

Kaedah ReentrantLock manakah yang membolehkan benang memperoleh lock atau kembali serta-merta tanpa menyekat jika lock tidak tersedia?

Rumusan: ReentrantLock berbanding synchronized

Perkara penting:

  • Kedua-duanya menyediakan eksklusi bersama dan kemasukan semula
  • ReentrantLock menambah: tryLock, lockInterruptibly, keadilan dan Condition
  • Sentiasa lepaskan dalam blok finally
  • synchronized lebih ringkas — utamakannya apabila cirinya mencukupi
  • ReentrantLock untuk senario lanjutan: had masa, kebolehan untuk diganggu dan berbilang Condition
Percuma untuk bermula

Pelajari Java dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
104
Pelajaran
374

Soalan Lazim

Adakah pelajaran “ReentrantLock berbanding synchronized” percuma?

Ya — teks penuh “ReentrantLock berbanding synchronized” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Java Academy, tingkat taraf kepada CoddyKit PRO. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “ReentrantLock berbanding synchronized”?

Bandingkan ciri ReentrantLock (tryLock, lockInterruptibly, keadilan) dengan kata kunci synchronized. Anda berlatih Java Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Java Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Java Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “ReentrantLock berbanding synchronized” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. ReentrantLock berbanding synchronized
  2. ReadWriteLock untuk Senario Pembaca-Penulis
  3. Pemboleh Ubah Atomik: Kemas Kini Tanpa Kunci
  4. StampedLock dan Bacaan Optimistik
← Kembali ke Java Academy