Java Concurrency - Khóa giao diện

Giao diện java.util.concurrent.locks.Lock được sử dụng như một cơ chế đồng bộ hóa luồng tương tự như các khối được đồng bộ hóa. Cơ chế Khóa mới linh hoạt hơn và cung cấp nhiều tùy chọn hơn so với một khối được đồng bộ hóa. Sự khác biệt chính giữa Khóa và khối được đồng bộ hóa là sau:

  • Guarantee of sequence- Khối được đồng bộ hóa không cung cấp bất kỳ đảm bảo nào về trình tự trong đó luồng chờ sẽ được cấp quyền truy cập. Giao diện khóa xử lý nó.

  • No timeout- Khối đồng bộ hóa không có tùy chọn thời gian chờ nếu khóa không được cấp. Giao diện khóa cung cấp tùy chọn như vậy.

  • Single method - Khối được đồng bộ hóa phải được chứa đầy đủ trong một phương thức trong khi các phương thức lock () và unlock () của giao diện khóa có thể được gọi trong các phương thức khác nhau.

Phương thức khóa

Sau đây là danh sách các phương thức quan trọng có sẵn trong lớp Khóa.

Sr.No. Phương pháp & Mô tả
1

public void lock()

Lấy khóa.

2

public void lockInterruptibly()

Có được khóa trừ khi luồng hiện tại bị gián đoạn.

3

public Condition newCondition()

Trả về một thể hiện Điều kiện mới được liên kết với thể hiện Khóa này.

4

public boolean tryLock()

Chỉ có được khóa nếu nó còn trống tại thời điểm yêu cầu.

5

public boolean tryLock()

Chỉ có được khóa nếu nó còn trống tại thời điểm yêu cầu.

6

public boolean tryLock(long time, TimeUnit unit)

Có được khóa nếu nó rảnh trong thời gian chờ nhất định và luồng hiện tại không bị gián đoạn.

7

public void unlock()

Mở khóa.

Thí dụ

Chương trình TestThread sau đây trình bày một số phương pháp này của giao diện Khóa. Ở đây chúng tôi đã sử dụng lock () để có được khóa và unlock () để mở khóa.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class PrintDemo {
   private final Lock queueLock = new ReentrantLock();

   public void print() {
      queueLock.lock();

      try {
         Long duration = (long) (Math.random() * 10000);
         System.out.println(Thread.currentThread().getName() 
            + "  Time Taken " + (duration / 1000) + " seconds.");
         Thread.sleep(duration);
      } catch (InterruptedException e) {
         e.printStackTrace();
      } finally {
         System.out.printf(
            "%s printed the document successfully.\n", Thread.currentThread().getName());
         queueLock.unlock();
      }
   }
}

class ThreadDemo extends Thread {
   PrintDemo  printDemo;

   ThreadDemo(String name,  PrintDemo printDemo) {
      super(name);
      this.printDemo = printDemo;
   }   

   @Override
   public void run() {
      System.out.printf(
         "%s starts printing a document\n", Thread.currentThread().getName());
      printDemo.print();
   }
}

public class TestThread {

   public static void main(String args[]) {
      PrintDemo PD = new PrintDemo();

      ThreadDemo t1 = new ThreadDemo("Thread - 1 ", PD);
      ThreadDemo t2 = new ThreadDemo("Thread - 2 ", PD);
      ThreadDemo t3 = new ThreadDemo("Thread - 3 ", PD);
      ThreadDemo t4 = new ThreadDemo("Thread - 4 ", PD);

      t1.start();
      t2.start();
      t3.start();
      t4.start();
   }
}

Điều này sẽ tạo ra kết quả sau.

Đầu ra

Thread - 1  starts printing a document
Thread - 4  starts printing a document
Thread - 3  starts printing a document
Thread - 2  starts printing a document
Thread - 1   Time Taken 4 seconds.
Thread - 1  printed the document successfully.
Thread - 4   Time Taken 3 seconds.
Thread - 4  printed the document successfully.
Thread - 3   Time Taken 5 seconds.
Thread - 3  printed the document successfully.
Thread - 2   Time Taken 4 seconds.
Thread - 2  printed the document successfully.

Chúng tôi đã sử dụng lớp ReentrantLock để triển khai giao diện Khóa ở đây. Lớp ReentrantLock cho phép một luồng khóa một phương thức ngay cả khi nó đã có khóa cho phương thức khác.