2015-10-11 15 views
7

Lock nesnesini, try...finally bloğuna eklendikten sonra aşağıdaki kodu almadan iyi programlama uygulaması olmadığını, böylece bir istisna atılmış olsa dahi kilidin serbest bırakılabileceğini okudum.Bir iş parçacığı bittiğinde bir kilit açıyor mu?

Basit bir soru gibi gelebilir: iş parçacığı bittiğinde bir iş parçacığına ait tüm kilitler otomatik olarak serbest bırakılıyor mu?

Bu soruyu sormamın nedeni, üzerinde çalıştığım programın, bir iş parçacığı bir kilit aldığında, işin bitmesine izin vermesinin bir nedeninin olmaması gerektiği. Ayrıca, kilitleri kullanmakta yeniyim, bu yüzden düşünemediğim tuzakların olup olmadığını merak ediyorum. İplik tamamlanmadan önce kodumda kilitleri serbest bırakmak için endişelenmem gerekiyor mu yoksa JVM'ye bırakabilir miyim, diğer bilgiler aktif olan tüm kilitlerin kilitlenmesini engeller. iplik durur? sana o kilidi gösterebilir

+0

Lütfen bir kod yazın. – C1sc0

+0

@ C1sc0: Ne hakkında bazı kodlar? Sorunun oldukça net bir sorun bildirimi var – Patrick

+0

Bunu muhtemelen çok basit bir uygulama ile test edebilirsiniz. İki iş parçacığı oluşturun, aynı kilidi temizleyin ve sonra iş parçacığını doğrudan öldürün. İkinci iplik kilidi alırsa, gerçekten kilidi açılır. – Patrick

cevap

3

Basit bir test ipliği fesih üzerine serbest bırakılmaz:

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

public class LockTest { 
    public static void main(String[] args) { 
     final Lock l = new ReentrantLock(); 

     Thread t = new Thread() { 
      @Override 
      public void run() { 
       System.out.println(Thread.currentThread()+": Acquire lock"); 
       l.lock(); 
       System.out.println(Thread.currentThread()+": Lock aquired: wait"); 
       LockSupport.parkNanos(1_000_000_000); 
       System.out.println(Thread.currentThread()+"; Exiting"); 
      } 
     }; 
     t.start(); 
     LockSupport.parkNanos(500_000_000); 
     System.out.println(Thread.currentThread()+": Acquire lock"); 
     l.lock(); 
     System.out.println(Thread.currentThread()+"; Success!"); 
    } 
} 

Çıktı: Ayrı iplik kilidi edinilen zaman, o zaman çıkıldı

Thread[Thread-0,5,main]: Acquire lock 
Thread[Thread-0,5,main]: Lock aquired: wait 
Thread[main,5,main]: Acquire lock 
Thread[Thread-0,5,main]; Exiting 
// "Success" is never written: stuck in dead-lock 

, kilit alınamaz ana iş parçacığı tarafından.

+0

Bu iş parçacığıyla belirli bir iş parçacığı tarafından elde edilen ilişkilendirilmiş kilitleri - API (biraz şaşırtıcı bir şekilde) bunu yapmak için görünmüyor. Özel bir iş parçacığı uygulamasında edinilen kilitlerin bir koleksiyonunu tutabilir ve iş parçacığının bitmesi için hemen önce hepsini serbest bırakabilirim. Bunun tuzaklara sahip olup olmadığını bilmiyorum ... –

+0

@OwenThomas, API kilidi kilitle ilişkilendiriyor. Başka bir iş parçacığından alınan kilit kilidini açmaya çalıştığınızda bunu kontrol edebilirsiniz: bir istisna alacaksınız. İplik bittikten sonra otomatik kilit açma, gereksiz çalışma ve gereksiz ek yükün çok fazla olması. –

+0

Geçerli iş parçacığı üzerinde çağırabileceğim bir yöntem var - getLocks() gibi bir şey - iş parçacığı kilitlerini içeren bir koleksiyon döndürüyor? –

İlgili konular