Java - Monitor Reentrant

Halo teman-teman masa depan para ahli Java! Hari ini, kita akan memulai perjalanan yang menarik ke dalam dunia Monitor Reentrant di Java. Jangan khawatir jika Anda baru dalam programming – saya akan menjadi panduan ramah Anda, dan kita akan mengambil ini langkah demi langkah. Jadi, pegang keyboard Anda (tongkat sihir), dan mari kita masuk!

Java - Reentrant Monitor

Apa Itu Monitor Reentrant?

Sebelum kita masuk ke hal-hal teknis, mari pahami apa itu Monitor Reentrant. Bayangkan Anda berada di perpustakaan ajaib di mana hanya satu orang yang dapat memasuki section tertentu pada saat yang sama. Sekarang, apa bila Anda sudah di section itu dan perlu masuk ke sub-section? Monitor Reentrant seperti sebuah pass ajaib yang memungkinkan Anda melakukan hal itu – masuk ke section yang Anda udah masuki!

Dalam istilah Java, Monitor Reentrant memungkinkan thread yang sudah memegang kunci untuk mengambilnya lagi tanpa memblok. Itu seperti memberikan izin kepada diri Anda untuk memasuki ruangan yang Anda udah masuki. Menarik, kan?

Mengapa Kita Butuh Monitor Reentrant?

Anda mungkin berpikir, "Mengapa kita butuh pass ajaib ini?" Di dunia multithreading (di mana beberapa bagian dari program berjalan secara bersamaan), kita sering perlu melindungi sumber daya bersama. Monitor Reentrant membantu kita melakukan ini lebih efisien, terutama saat kita memiliki metode yang memanggil metode lain yang juga memerlukan kunci yang sama.

Mengenalkan ReentrantLock

Java menyediakan kelas ReentrantLock untuk mengimplementasikan Monitor Reentrant. Itu seperti pass perpustakaan ajaib, tapi dalam bentuk kode!

Sintaks

Berikut cara kita membuat dan menggunakan ReentrantLock:

import java.util.concurrent.locks.ReentrantLock;

ReentrantLock lock = new ReentrantLock();

// Untuk mengunci
lock.lock();
try {
// Kode Anda yang dilindungi disini
} finally {
// Untuk melepaskan kunci
lock.unlock();
}

Jangan khawatir jika ini terlihat agak menakutkan. Kita akan membongkar ini dengan beberapa contoh!

Multithreading Tanpa Reentrant Lock

mari mulai dengan contoh sederhana tanpa menggunakan ReentrantLock. Bayangkan kita punya counter ajaib yang beberapa ahli sihir (thread) mencoba untuk menambahnya:

public class MagicalCounter {
private int count = 0;

public void increment() {
count++;
}

public int getCount() {
return count;
}
}

Sekarang, mari kita buat beberapa thread ahli sihir untuk menambah counter ini:

public class WizardThread extends Thread {
private MagicalCounter counter;

public WizardThread(MagicalCounter counter) {
this.counter = counter;
}

public void run() {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
}
}

public class MagicalCounterTest {
public static void main(String[] args) throws InterruptedException {
MagicalCounter counter = new MagicalCounter();
WizardThread wizard1 = new WizardThread(counter);
WizardThread wizard2 = new WizardThread(counter);

wizard1.start();
wizard2.start();

wizard1.join();
wizard2.join();

System.out.println("Jumlah akhir: " + counter.getCount());
}
}

Jika Anda menjalankan ini, Anda mungkin mengharapkan jumlah akhir menjadi 2000 (1000 penambahan dari setiap ahli sihir). Tetapi keseruan! Hasilnya sering kurang dari 2000. Ini karena ahli sihir kita berjalan atas kaki satu sama lain – mereka mencoba menambah counter pada saat yang sama, menyebabkan penambahan hilang.

Multithreading Dengan Reentrant Lock

Sekarang, mari kita menambahkan sedikit magi ReentrantLock pada counter kita:

import java.util.concurrent.locks.ReentrantLock;

public class MagicalCounterWithLock {
private int count = 0;
private ReentrantLock lock = new ReentrantLock();

public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}

public int getCount() {
return count;
}
}

mariuraikan ini:

  1. Kita membuat objek ReentrantLock yang disebut lock.
  2. Dalam metode increment, kita panggil lock.lock() sebelum menambah counter.
  3. Kita gunakan blok try-finally untuk memastikan kita selalu melepaskan kunci, bahkan jika terjadi eksepsi.
  4. Setelah menambah, kita panggil lock.unlock() di blok finally.

Sekarang, jika kita menjalankan tes WizardThread dengan MagicalCounterWithLock ini, kita akan selalu mendapatkan 2000 sebagai jumlah akhir. Ahli sihir kita sekarang saling mengambil giliran dengan baik!

Multithreading Dengan Reentrant Lock Sebagai Benar

ReentrantLock memiliki trik lain di dadanya. Kita dapat membuatnya dengan parameter keadilan:

ReentrantLock fairLock = new ReentrantLock(true);

Ketika kita mengatur keadilan ke true, kunci mengutamakan memberikan akses ke thread yang menunggu terlama. Itu seperti membentuk antrian yang benar bagi ahli sihir kita!

Berikut cara kita menggunakannya:

public class FairMagicalCounter {
private int count = 0;
private ReentrantLock fairLock = new ReentrantLock(true);

public void increment() {
fairLock.lock();
try {
count++;
} finally {
fairLock.unlock();
}
}

public int getCount() {
return count;
}
}

Ini memastikan bahwa jika beberapa ahli sihir menunggu untuk menambah counter, yang pertama kali menunggu akan mendapat giliran berikutnya.

Kesimpulan

Dan begitu, para ahli sihir muda! Kita telah menjalani perjalanan yang menarik ke dalam dunia Monitor Reentrant di Java. Kita telah melihat bagaimana mereka membantu kita mengelola akses bersamaan ke sumber daya bersama di lingkungan multithreading, memastikan counter ajaib kita (dan objek bersama lainnya) dinaikkan dengan benar.

Ingat, seperti segala macam sihir yang kuat, Monitor Reentrant harus digunakan bijaksana. Mereka sangat baik untuk mengelola akses bersamaan ke sumber daya bersama, tetapi penggunaan berlebihan dapat menyebabkan penurunan performa atau bahkan deadlock (suatu situasi di mana ahli sihir saling menunggu kunci satu sama lain selamanya!).

Praktik spells... err, contoh kode ini, dan segera Anda akan menjadi ahli memakai sihir multithreading seperti seorang pro! Semangat coding, dan may your threads always be in harmony!

Credits: Image by storyset