Java中的可重入锁


ReentrantLock 是一个实现了 Lock 接口的类。它提供了高度灵活的同步功能,因此它是 Java 中使用最广泛的锁类。它对于线程的可靠和公平运行是必要的。在这里,线程是大型操作的小型子进程。在本文中,我们将学习 ReentrantLock 以及它们如何管理线程以高效地工作。

ReentrantLock 的工作原理

当多个线程尝试访问共享资源时,ReentrantLock 通过 `lock()` 和 `unlock()` 方法一次限制一个线程访问。假设有三个试图预订火车票的人。同时,这三个人都会尝试访问预订系统,可能会发生两个人预订了同一个座位的情况。Reentrant Lock 可以处理这种情况。

首先,这三个人都会通过 `tryLock()` 方法请求获取预订系统。当一个人获取预订系统后,它会通过 `lock()` 方法限制特定的座位预订。预订后,这个人会调用 `unlock()` 方法释放已获取的锁。在资源繁忙期间,其他人会在队列中等待轮到他们,并在锁释放后进入可运行状态。

ReentrantLock 试图以公平的方式提供锁。我们可以设置线程可以获取锁的时间长度,并且它确保等待时间最长的线程可能首先获得访问锁的权限。默认情况下,锁是不公平的,要使其公平,我们需要在其构造函数中传递布尔值“true”。

语法

ReentrantLock nameOflock = new  ReentrantLock(); 
// by default false
Or,
ReentrantLock nameOflock = new  ReentrantLock(true); 
// we can make it true

锁是显式的,可以按任何顺序锁定或解锁。单个线程可以多次请求锁,这就是锁名为 Reentrant 的原因。我们可以使用 `getHoldCount()` 方法计算锁被获取的次数。

示例

以下示例说明了 Reentrant Lock 的用法。

代码工作原理

  • 创建一个名为“Thrd”的类,并在该线程中定义一个 ReentrantLock 对象。

  • 定义一个名为“operation()”的方法,并带有一个整数类型的参数。将 `tryLock()` 方法的布尔值存储到名为“lockAcquired”的变量中,该变量将检查锁是否被任何线程获取。

  • 如果获取了锁,则使用 `lock()` 方法将锁赋予该线程,并让线程执行给定的任务。

  • 该任务将在 try 块中执行,锁将在 finally 块中使用 `unlock()` 方法释放。

  • 现在创建三个线程类并调用 `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 类及其方法的实际实现。

更新于:2023年5月16日

335 次浏览

启动您的职业生涯

通过完成课程获得认证

开始学习
广告