Kunci ialah antara muka peringkat teratas, dan semua kaedahnya adalah seperti yang ditunjukkan di bawah:
Senarai subkelasnya adalah seperti berikut:
Kami biasanya menggunakan ReentrantLock untuk mentakrifkan kejadiannya, Hubungan antara mereka adalah seperti yang ditunjukkan di bawah:
PS: Sync bermaksud kunci penyegerakan, FairSync bermaksud kunci adil dan NonfairSync bermaksud kunci tidak adil.
Mempelajari sebarang kemahiran bermula dengan menggunakannya, jadi kita tidak terkecuali Mari lihat penggunaan asas ReentrantLock dahulu:
public class LockExample { // 创建锁对象 private final ReentrantLock lock = new ReentrantLock(); public void method() { // 加锁操作 lock.lock(); try { // 业务代码...... } finally { // 释放锁 lock.unlock(); } } }
. Selepas ReentrantLock dicipta, terdapat dua operasi utama:
Operasi kunci: lock()
Lepaskan operasi kunci : buka kunci()
Ramai orang akan berfikir bahawa (Terutama untuk rakan baru) , pelaksanaan lalai ReentrantLock ialah kunci adil, tetapi ini tidak berlaku secara lalai ReentrantLock ialah kunci tidak adil (ini terutamanya disebabkan oleh pertimbangan prestasi),
Sebagai contoh, seperti berikut Ini. kod:
import java.util.concurrent.locks.ReentrantLock; public class LockExample { // 创建锁对象 private static final ReentrantLock lock = new ReentrantLock(); public static void main(String[] args) { // 定义线程任务 Runnable runnable = new Runnable() { @Override public void run() { // 加锁 lock.lock(); try { // 打印执行线程的名字 System.out.println("线程:" + Thread.currentThread().getName()); } finally { // 释放锁 lock.unlock(); } } }; // 创建多个线程 for (int i = 0; i < 10; i++) { new Thread(runnable).start(); } } }
Keputusan pelaksanaan program di atas adalah seperti berikut:
Seperti yang dapat dilihat daripada di atas keputusan pelaksanaan , ReentrantLock ialah kunci yang tidak adil secara lalai. Oleh kerana nama benang ditambah mengikut susunan di mana ia dicipta, jika ia adalah kunci yang adil, maka pelaksanaan benang harus meningkat mengikut susunan Walau bagaimanapun, seperti yang dapat dilihat dari keputusan di atas, pelaksanaan dan pencetakan urutan tidak teratur ini Penerangan ReentrantLock ialah kunci yang tidak adil secara lalai.
Sangat mudah untuk menetapkan ReentrantLock sebagai kunci adil Anda hanya perlu menetapkan parameter pembinaan sebenar apabila mencipta ReentrantLock Seperti yang ditunjukkan dalam kod berikut:
rreee <🎜. >Keputusan pelaksanaan program di atas adalah seperti berikut:
Seperti yang dapat dilihat daripada keputusan di atas, apabila kami secara eksplisit menetapkan pembina sebenar untuk ReentrantLock Selepas melepasi parameter, ReentrantLock menjadi kunci adil, dan susunan benang memperoleh kunci menjadi teratur. Malah, daripada kod sumber ReentrantLock, kita juga boleh melihat sama ada ia adalah kunci adil atau kunci tidak adilSebahagian daripada kod sumber ReentrantLock dilaksanakan seperti berikut: <. 🎜>import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// 创建锁对象(公平锁)
private static final ReentrantLock lock = new ReentrantLock(true);
public static void main(String[] args) {
// 定义线程任务
Runnable runnable = new Runnable() {
@Override
public void run() {
// 加锁
lock.lock();
try {
// 打印执行线程的名字
System.out.println("线程:" + Thread.currentThread().getName());
} finally {
// 释放锁
lock.unlock();
}
}
};
// 创建多个线程
for (int i = 0; i < 10; i++) {
new Thread(runnable).start();
}
}
}
2. Lepaskan kunci masuk akhirnya
Apabila menggunakan ReentrantLock, anda mesti ingat untuk melepaskan kunci, jika tidak kunci akan diduduki selama-lamanya, dan benang lain yang menggunakan kunci akan menjadi diduduki secara kekal. Tunggu, jadi apabila kita menggunakan ReentrantLock, kita mesti melepaskan kunci masuk akhirnya, untuk memastikan bahawa kunci akan dilepaskan.
Contoh balas public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
Daripada perkara di atas, dapat dilihat daripada keputusan bahawa apabila pengecualian berlaku, kunci tidak dilepaskan secara normal, yang akan menyebabkan benang lain yang menggunakan kunci berada dalam keadaan menunggu secara kekal.
Contoh positifimport java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// 创建锁对象
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// 加锁操作
lock.lock();
System.out.println("Hello,ReentrantLock.");
// 此处会报异常,导致锁不能正常释放
int number = 1 / 0;
// 释放锁
lock.unlock();
System.out.println("锁释放成功!");
}
}
Daripada Ia boleh dilihat daripada keputusan di atas bahawa walaupun pengecualian berlaku dalam kaedah, ia tidak menjejaskan operasi pelepasan kunci ReentrantLock, supaya benang lain yang menggunakan kunci ini boleh memperoleh dan berjalan secara normal.
3 Kunci tidak boleh dilepaskan beberapa kali
Satu kunci sepadan dengan dua operasi buka kunci, menyebabkan atur cara melaporkan ralat dan menamatkan pelaksanaan Kod sampel adalah seperti berikut:
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
// 创建锁对象
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
// 加锁操作
lock.lock();
try {
System.out.println("Hello,ReentrantLock.");
// 此处会报异常
int number = 1 / 0;
} finally {
// 释放锁
lock.unlock();
System.out.println("锁释放成功!");
}
}
}
Daripada keputusan di atas, dapat dilihat bahawa apabila buka kunci kedua dilaksanakan, program melaporkan ralat dan menamatkan pelaksanaan , menyebabkan kod selepas pengecualian tidak dilaksanakan seperti biasa.
在使用 ReentrantLock 时,需要注意不要将加锁操作放在 try 代码中,这样会导致未加锁成功就执行了释放锁的操作,从而导致程序执行异常。
反例
import java.util.concurrent.locks.ReentrantLock; public class LockExample { // 创建锁对象 private static final ReentrantLock lock = new ReentrantLock(); public static void main(String[] args) { try { // 此处异常 int num = 1 / 0; // 加锁操作 lock.lock(); } finally { // 释放锁 lock.unlock(); System.out.println("锁释锁"); } System.out.println("程序执行完成."); } }
以上程序的执行结果如下:
从上述结果可以看出,如果将加锁操作放在 try 代码中,可能会导致两个问题:
未加锁成功就执行了释放锁的操作,从而导致了新的异常;
释放锁的异常会覆盖程序原有的异常,从而增加了排查问题的难度。
Atas ialah kandungan terperinci Apakah perangkap biasa ReentrantLock di Jawa?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!