16 Eylül 2019 Pazartesi

ReentrantLock Sınıfı - Read ve Write Farkı Gözetmez

Giriş
Şu satırları dahil ederiz.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
java.util.concurrent.locks.Lock arayüzünden kalıtır. Bu arayüzü gerçekleştiren sınıflar şöyle
- ReentrantLock, 

Aynı thread mutex'i bir kere kilitledikten sonra tekrar kilitleyebilir.  Eğer ve Read ve Write farkını gözetmek istersek ReentrantReadWriteLock kullanılır

ReentrantLock Extrinsic Çalışır
Açıklaması şöyle. Intrinsic içsel anlamına gelir. Lock içeride olduğu için kontrol edemeyiz. Extrinsic dışsal anlamına gelir. Lock'ı biz kontrol ederiz.
In intrinsic locks, acquire-release pairs are block-structured. In other words, a lock is always released in the same basic block in which it was acquired, regardless of how control exits the block. Extrinsic locks allow the facility to have more explicit control. 
ReentrantLock İçini Görmek İçin Çeşitli Metodlar Sunar
Açıklaması şöyle
It provides methods for monitoring the state of the lock ,for instance 
- to check number of threads waiting for the resource(getQueueLength()), 
- to check whether a specific thread is waiting for the lock(hasQueuedThread(Thread thread)).

Dikkat
ReentrantLock  her zaman try/finally şeklinde kullanılmalıdır. Eğer finally içinde unlock() işlemi yapılmazsa, metodumuz exception fırlatırsa, lock sonsuza kadar kilitli kalabilir. BunuAutoCloseable ile  otomatik hale getirmek için şöyle yaparız
public class ClosableLock implements AutoCloseable {
  private final ReentrantLock lock;

  public ClosableLock() {
    this.lock = new ReentrantLock();
  }

  public ClosableLock(boolean fair) {
    this.lock = new ReentrantLock(fair);
  }

  @Override
  public void close() throws Exception {
    lock.unlock();
  }

  public ClosableLock lock() {
    lock.lock();
    return this;
 }

  public ClosableLock lockInterruptibly() throws InterruptedException {
    lock.lock();
    return this;
  }

  public void unlock() {
    lock.unlock();
  }
}

constructor
Şöyle yaparız.
Lock lock = new ReentrantLock();
constructor - boolean
Açıklaması şöyle. Bu sınıf constructor içine true verirsek uzun zamandır bekleyen thread'lere adil (fair) davranır.
A second constructor takes a boolean to indicate whether or not the lock should apply a fairness policy. If set to true, a fairness policy is implemented that ensures that the longest waiting thread will acquire the lock when it becomes available. This avoids high priority threads monopolizing CPU time, while lower-priority threads are left to wait for long periods.
Şöyle yaparız.
Lock lock = new ReentrantLock(true);
getWaitQueueLength metodu 
Lock arayüzünden gelir. İmzası şöyle
getWaitQueueLength(Condition condition) 
getWaitingThreads metodu
Lock arayüzünden gelir. İmzası şöyle
getWaitingThreads(Condition condition) 
hasWaiters metodu
newConditon() ile yaratılan condition nesnesi üzerinde bekleyen thread oldup olmadığını döner.

lock metodu
Şöyle yaparız.
public void methodA() {
    lock.lock();
    try {
        // Write something to a file.
    } finally {
        lock.unlock();
    }
}
lockInterruptibly metodu
Açıklaması şöyle
Thread tries to acquire the lock unless the current thread is interrupted allowing it to immediately react to the interrupt signal.
Açıklaması şöyle
lockInterruptibly() lets us interrupt a thread while it’s waiting for a lock. This is an interesting feature but again, hard to find a situation where it would realistically make a difference. If you write code that must be very responsive for interrupting you would need to use the lockInterruptibly() API to gain that capability. But how long do you spend within the lock() method on average?
Şöyle yaparız
ReentrantLock lock = new ReentrantLock();
public void run() {
  lock.lockInterreptibly();
  try {
    ...
  } finally {
    lock.unlock();
  }
}
isLocked metodu
Şöyle yaparız.
if (!lock.isLocked()) {
  lock.lock();
  ...
}
newCondition metodu
Şöyle yaparız.
Condition condition  = lock.newCondition();
tryLock metodu
Şöyle yaparız.
if (lock.tryLock()) {
  try {
    // Use your synchronized resource here
  } finally {
    lock.unlock();
  }
} else {
  // Failed to lock
}
unlock metodu
Eğer lock() ile kilitlenmemiş bir nesneyi unlock() ile bırakmaya çalışırsak şu exception fırlatılır.
java.lang.IllegalMonitorStateException
Örnek
Şöyle yaparız.
Lock lock = new ReentrantLock();
try{
  lock.lock();
  someFunctionLikelyToCauseAnException();
}
catch(e){...}
finally {
  lock.unlock();
}






Hiç yorum yok:

Yorum Gönder