Dalam contoh methodA dan methodB adalah metode instance (sebagai lawan dari metode statis). Menempatkan synchronized
metode instance berarti bahwa utas harus mendapatkan kunci ("kunci intrinsik") pada objek contoh di mana metode dipanggil sebelum utas dapat mulai mengeksekusi kode apa pun dalam metode itu.
Jika Anda memiliki dua metode instance berbeda yang ditandai tersinkronisasi dan utas berbeda memanggil metode-metode tersebut secara bersamaan pada objek yang sama, utas tersebut akan bersaing untuk kunci yang sama. Setelah satu utas mendapatkan kunci, semua utas lainnya akan ditutup dari semua metode instance yang disinkronkan pada objek itu.
Agar kedua metode dapat berjalan secara bersamaan, mereka harus menggunakan kunci yang berbeda, seperti ini:
class A {
private final Object lockA = new Object();
private final Object lockB = new Object();
public void methodA() {
synchronized(lockA) {
//method A
}
}
public void methodB() {
synchronized(lockB) {
//method B
}
}
}
di mana sintaksis blok yang disinkronkan memungkinkan menentukan objek tertentu yang perlu dijalankan utas pelaksana untuk mendapatkan kunci intrinsik agar dapat memasuki blok.
Yang penting untuk dipahami adalah bahwa meskipun kami menempatkan kata kunci "tersinkronisasi" pada metode individual, konsep intinya adalah kunci intrinsik di belakang layar.
Berikut adalah cara tutorial Java menjelaskan hubungan:
Sinkronisasi dibangun di sekitar entitas internal yang dikenal sebagai kunci intrinsik atau kunci monitor. (Spesifikasi API sering merujuk pada entitas ini hanya sebagai "monitor.") Kunci intrinsik berperan dalam kedua aspek sinkronisasi: menegakkan akses eksklusif ke keadaan objek dan membangun hubungan sebelum terjadi yang penting untuk visibilitas.
Setiap objek memiliki kunci intrinsik yang terkait dengannya. Dengan konvensi, utas yang membutuhkan akses eksklusif dan konsisten ke bidang objek harus memperoleh kunci intrinsik objek sebelum mengaksesnya, dan kemudian melepaskan kunci intrinsik ketika dilakukan dengan mereka. Sebuah thread dikatakan memiliki kunci intrinsik antara waktu kunci tersebut diperoleh dan melepaskan kunci tersebut. Selama utas memiliki kunci intrinsik, tidak ada utas lain yang bisa mendapatkan kunci yang sama. Utas lainnya akan memblokir ketika mencoba untuk mendapatkan kunci.
Tujuan dari penguncian adalah untuk melindungi data yang dibagikan. Anda akan menggunakan kunci terpisah seperti yang ditunjukkan dalam kode contoh di atas hanya jika setiap kunci melindungi anggota data yang berbeda.