Java Eşzamanlılığı - Arayüzü Kilitle

Bir java.util.concurrent.locks.Lock arayüzü, senkronize bloklara benzer bir iş parçacığı senkronizasyon mekanizması olarak kullanılır. Yeni Kilitleme mekanizması daha esnektir ve senkronize bir bloktan daha fazla seçenek sunar. Kilit ve senkronize blok arasındaki temel farklar şunlardır -

  • Guarantee of sequence- Senkronize blok, bekleyen iş parçacığına erişimin verileceği herhangi bir sıra garantisi sağlamaz. Kilit arayüzü bunu halleder.

  • No timeout- Senkronize blok, kilit verilmemişse zaman aşımı seçeneğine sahip değildir. Kilit arayüzü böyle bir seçenek sağlar.

  • Single method - Senkronize blok, tek bir yöntem içinde tamamen yer almalıdır, oysa bir kilit arayüzünün yöntemleri lock () ve unlock () farklı yöntemlerle çağrılabilir.

Kilit Yöntemleri

Kilit sınıfında bulunan önemli yöntemlerin listesi aşağıdadır.

Sr.No. Yöntem ve Açıklama
1

public void lock()

Kilidi alır.

2

public void lockInterruptibly()

Mevcut iş parçacığı kesilmediği sürece kilidi alır.

3

public Condition newCondition()

Bu Lock örneğine bağlı yeni bir Koşul örneği döndürür.

4

public boolean tryLock()

Kilidi, yalnızca çağrı sırasında boşsa alır.

5

public boolean tryLock()

Kilidi, yalnızca çağrı sırasında boşsa alır.

6

public boolean tryLock(long time, TimeUnit unit)

Verilen bekleme süresi içinde serbest kalırsa ve mevcut iş parçacığı kesintiye uğramamışsa kilidi alır.

7

public void unlock()

Kilidi açar.

Misal

Aşağıdaki TestThread programı, Kilit arayüzünün bu yöntemlerinden bazılarını göstermektedir. Burada kilidi elde etmek için lock () ve kilidi açmak için unlock () kullandık.

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();
   }
}

Bu, aşağıdaki sonucu verecektir.

Çıktı

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.

ReentrantLock sınıfını burada Lock arayüzünün bir uygulaması olarak kullandık. ReentrantLock sınıfı, bir iş parçacığının bir yöntemi kilitlemesine izin verir, hatta başka bir yöntemde kilit zaten olsa bile.