Sebagai alat untuk berbagi data secara bersamaan dan memastikan konsistensi, kunci memiliki banyak implementasi pada platform JAVA (seperti tersinkronisasi dan ReentrantLock, dll.). Kunci yang sudah tertulis ini memberikan kemudahan bagi pengembangan kami, namun sifat spesifik dan jenis kunci jarang disebutkan. Rangkaian artikel ini akan menganalisis nama dan karakteristik kunci umum di JAVA untuk menjawab pertanyaan Anda.
4. Kunci masuk kembali:
Artikel ini membahas tentang kunci reentrant dalam arti luas, bukan hanya ReentrantLock di JAVA.
Kunci reentrant, juga disebut kunci rekursif, berarti bahwa setelah fungsi luar dari thread yang sama memperoleh kunci, fungsi rekursif dalam masih memiliki kode untuk memperoleh kunci tersebut, namun tidak terpengaruh.
Di lingkungan JAVA, ReentrantLock dan tersinkronisasi keduanya merupakan kunci reentrant.
Berikut adalah contoh penggunaan:
Copy kode kodenya sebagai berikut:
Tes kelas publik mengimplementasikan Runnable{
void get() yang disinkronkan secara publik(){
System.out.println(Thread.currentThread().getId());
mengatur();
}
set kekosongan yang disinkronkan publik(){
System.out.println(Thread.currentThread().getId());
}
@Mengesampingkan
menjalankan kekosongan publik() {
mendapatkan();
}
public static void main(String[] args) {
Tes ss=Tes baru();
Utas baru(ss).mulai();
Utas baru(ss).mulai();
Utas baru(ss).mulai();
}
}
Hasil akhir dari kedua contoh tersebut benar, yaitu ID thread yang sama dikeluarkan dua kali berturut-turut.
Hasilnya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
Benang: 8
Benang: 8
Benang: 10
Benang: 10
Benang: 9
Benang: 9
Peran terbesar dari kunci masuk kembali adalah untuk menghindari kebuntuan.
Mari kita ambil spin lock sebagai contoh.
Copy kode kodenya sebagai berikut:
SpinLock kelas publik {
pribadi AtomicReference<Thread> pemilik = AtomicReference baru<>();
kunci kekosongan publik(){
Thread saat ini = Thread.currentThread();
while(!owner.compareAndSet(null, saat ini)){
}
}
buka kunci kekosongan publik (){
Thread saat ini = Thread.currentThread();
pemilik.compareAndSet(saat ini, null);
}
}
Untuk kunci putar:
1. Jika thread yang sama memanggil lock() sebanyak dua kali, maka akan menyebabkan posisi lock dipanggil untuk kedua kalinya berputar. (Dalam fungsi kunci, Anda harus memverifikasi apakah utas tersebut adalah utas yang telah memperoleh kunci)
2. Jika masalah 1 telah terpecahkan, kunci akan dilepaskan saat unlock() dipanggil untuk pertama kali. Kuncinya seharusnya tidak dibuka.
(Menggunakan waktu penghitungan untuk statistik)
Setelah dimodifikasi, tampilannya sebagai berikut:
Copy kode kodenya sebagai berikut:
kelas publik SpinLock1 {
pribadi AtomicReference<Thread> pemilik = AtomicReference baru<>();
jumlah int pribadi =0;
kunci kekosongan publik(){
Thread saat ini = Thread.currentThread();
if(saat ini==pemilik.dapatkan()) {
hitung++;
kembali ;
}
while(!owner.compareAndSet(null, saat ini)){
}
}
buka kunci kekosongan publik (){
Thread saat ini = Thread.currentThread();
if(saat ini==pemilik.dapatkan()){
jika(hitung!=0){
menghitung--;
}kalau tidak{
pemilik.compareAndSet(saat ini, null);
}
}
}
}
Kunci putar ini adalah kunci masuk kembali.