Java 可重入锁
可重入锁是实现锁接口的一个类。它提供了灵活的同步特性,因此是Java中使用最广泛的锁类。它对线程的可靠和公平工作是必需的。在这里,线程是一个大操作的小子过程。在本文中,我们将学习可重入锁以及它们如何管理线程以使其能够有效工作。
可重入锁的工作原理
当多个线程尝试访问共享资源时,可重入锁通过 ‘lock()’ 和 ‘unlock()’ 方法限制一次只能有一个线程访问。假设有三个人试图预订火车票。在同一时间,这三个人将尝试访问预订系统,可能会发生两个人预订了相同的座位。可重入锁可以处理这种情况。
首先,这三个人将请求通过 ‘tryLock()’ 方法获取预订系统。当一个人获取预订系统时,它通过 ‘lock()’ 方法限制特定座位的预订。预订完成后,该人将调用 ‘unlock()’ 方法释放已获取的锁。在资源忙碌时,其他人将在队列中等待,轮到他们时,锁释放后他们将进入可运行状态。
可重入锁尝试以公平的方式提供锁。我们可以设置线程可以获取锁的时间以及确保等待时间最长的线程首先获得锁。默认情况下,锁是不公平的,如果要使其公平,需要在其构造函数中传递布尔值 ‘true’。
语法
ReentrantLock nameOflock = new ReentrantLock();
// by default false
Or,
ReentrantLock nameOflock = new ReentrantLock(true);
// we can make it true
锁是明确的,可以以任意顺序锁定或解锁。单个线程可以多次请求锁,这就是锁的名称为可重入锁的原因。我们可以使用‘getHoldCount()’方法计算锁被获取的次数。
示例
以下示例说明了可重入锁的使用。
代码工作原理
- 创建一个名为‘Thrd’的类,并在该线程内部定义一个ReentrantLock对象。
-
定义一个带有整型参数的‘operation()’方法。将‘tryLock()’方法的布尔值保存到名为‘lockAcquired’的变量中,以检查是否有任何线程获取了锁。
-
如果获取到锁,请使用‘lock()’方法将锁赋予该线程,并让线程执行给定的任务。
-
任务将在try块中执行,并使用‘unlock()’方法在finally块中释放锁。
-
现在创建三个线程类,并调用‘operation()’方法。
-
在main()方法中,定义三个线程类的对象,并调用它的‘start()’方法来启动线程的执行。
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
class Thrd {
// creating object of ReentrantLock class
private static ReentrantLock lockr = new ReentrantLock();
static void operation(int data) {
// give access to lock
boolean lockAcquired = lockr.tryLock();
if (lockAcquired) {
try {
lockr.lock();
// giving lock to thread
for(int i = 1; i <= 4; i++) {
System.out.println(data++);
}
// checking lock count
System.out.println("Count of Lock: " + lockr.getHoldCount());
} finally {
lockr.unlock();
// unlocking the lock
}
} else {
System.out.println("I am in else block");
}
}
}
class Thrd1 extends Thread {
// thread number 1
public void run() {
Thrd.operation(1);
// method calling
}
}
class Thrd2 extends Thread {
// thread number 2
public void run() {
Thrd.operation(5);
// method calling
}
}
class Thrd3 extends Thread {
// thread number 3
public void run() {
Thrd.operation(10);
// method calling
}
}
public class ThrdExecution {
public static void main(String args[]) {
// creating object for thread class
Thrd1 oprt1 = new Thrd1();
Thrd2 oprt2 = new Thrd2();
Thrd3 oprt3 = new Thrd3();
// Starting the thread operation
oprt1.start();
oprt2.start();
oprt3.start();
}
}
输出
1
2
3
4
I am in else block
I am in else block
Count of Lock: 2
结论
在本文中,我们学习了ReentrantLock类及其内置方法‘lock()’、‘unlock()’和‘trylock()’的使用。此外,我们创建了一个Java程序,演示了ReentrantLock类及其方法的实际应用。