Kilit nesnesinin neden statik olması gerekiyor?


112

Çoklu iş parçacığı içinde kilitlemek için özel bir statik salt okunur nesne kullanmak çok yaygındır. Özelin, kapsüllemeyi sıkıştırarak kilit nesnesine giriş noktalarını azalttığını ve dolayısıyla en önemli olana erişim sağladığını anlıyorum.

Ama neden statik?

private static readonly object Locker = new object();

Sonunda, alan yalnızca benim sınıfımda kullanılıyor ve bunun yerine şunu da kullanabilirim:

private readonly object Locker = new object();

Herhangi bir yorum?

GÜNCELLEME:

Örnek olarak bu kodu yapıştırdım (sadece bir örnek). Bunun için statik veya statik olmayan dolap kullanabilirim ve her ikisi de iyi çalışır. Aşağıdaki cevabı göz önünde bulundurarak daha çok dolabımı böyle mi tanımlamalıyım? (Özür dilerim, önümüzdeki hafta bir röportajım var ve her ayrıntıyı bilmem gerekiyor :)

private readonly object Locker = new object();

Ve işte kod:

    private int _priceA;
    private int _priceB;
    private EventWaitHandle[] _waithandle;
    private readonly IService _service;

//ctor
public ModuleAViewModel(IService service)
    {
        _service = service;
        _modelA = new ModelA();
        _waithandle = new ManualResetEvent[2];
        _waithandle[0] = new ManualResetEvent(false);
        _waithandle[1] = new ManualResetEvent(false);
        LoadDataByThread();
    }


 private void LoadDataByThread()
        {
            new Thread(() =>
                           {
                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceA = _service.GetPriceA();
                                   }
                                   _waithandle[0].Set();
                               }).Start();

                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceB = _service.GetPriceB();
                                   }
                                   _waithandle[1].Set();
                               }).Start();

                               WaitHandle.WaitAll(_waithandle);
                               PriceA = _priceA;
                               PriceB = _priceB;
                           }).Start();
        }

Teşekkürler


15
Bildiğim kadarıyla, statik genellikle onu örnek-bağımsız yapmak için kullanılır. Birden fazla "MyWorkerClass" örneği mevcutsa, bir seferde yalnızca biri verilen verilerle çalıştırılabilir (hepsinin paylaşılan kaynakları kullandığı varsayılırsa).
Brad Christie

2
Düzenleme önemli bir ayrıntı içermiyor: nerede _serviceve nerede _waithandlebulunuyor? örneği? statik? diğer? Yani olabilir , örneğin, ... bir uzak sunucuya kasten senkronize erişim olmak
Marc Gravell

doğru, ikinci düzenlemeyle: evet, her örnek için kilitleyebileceğiniz şeylerin bu ucundan. Yine de statik hale getirmek için nedenler olabilir - orijinal geliştirici (belirtildiği gibi) erişimi senkronize etmek istiyorsa, böylece sunucu bu AppDomain'den aynı anda yalnızca bir istek alırsa ... Durumun bu olup olmadığını bilemiyorum ya da sadece tesadüfi olup olmadığı.
Marc Gravell

Yanıtlar:


177

"Çoklu iş parçacığında kilitlemek için özel bir statik salt okunur nesne kullanmak çok yaygın değildir" - daha ziyade, uygun / seçilen ayrıntı düzeyinde bir kilit kullanmak yaygındır . Bazen bu static. Daha sık olarak, IMO değildir - ancak örnek tabanlıdır.

Bir statickilit gördüğünüz ana zaman , genel bir önbellek veya genel verilerin / tekillerin ertelenmiş yüklemesi içindir. Ve ikincisinde, yine de yapmanın daha iyi yolları var .

Yani gerçekten bağlıdır: Lockersenaryonuzda nasıl kullanılıyor? Öyle bir şey koruyor kendisi statik? Öyleyse, kilit statik olmalıdır. Örnek tabanlı bir şeyi koruyorsa , IMO kilidi de örnek tabanlı olmalıdır .


24
Küresel verilerin yüklenmesini ertelemenin daha iyi bir yolu hakkında daha fazla ayrıntı verebilir misiniz?
bizi

Ben her zaman bir statik / uçucu kullanırım çünkü örnek tabanlı olduğu birkaç yer varsa, yine de yöntemime / değişkenime iş parçacığı güvenli bir şekilde erişilmesini kontrol etmek isterim. Birçok örnek aynı kaynaklara erişiyor olabilir ve bunu kontrol etmek istiyorum. Ben de bunu yapmanın daha iyi olduğunu görmek isterim. Harika bir temsilciniz var ve eminim ki cevabınız benim için benim için aynı derecede harika olacaktır. Lütfen cevap verin?
Andrew Simpson

82

Statik olması gerekmez , hatta bazen durağan olmaması gerekir.

Değişken, onu kilitleme için kullandığınız yöntemlerle aynı kapsamda yaşamalıdır. Yöntemler statikse, değişken statik olmalıdır ve yöntemler örnek yöntemler ise, değişken bir örnek değişken olmalıdır.

Bir örnek yönteminde kilitlemek için kullanıldığında statik bir değişken yine de çalışacaktır, ancak o zaman çok fazla kilitleyeceksiniz. Yalnızca aynı örnekteki yöntemleri değil, tüm örneklerdeki tüm yöntemleri kilitleyeceksiniz.


28
"A-ha" için +1 ... Sadece aynı durumdaki yöntemleri değil, tüm durumlarda tüm yöntemleri kilitleyeceksiniz.
radarbob

3
@radarbob - Küçük detay: Daha fazla müşterinin ilgisini çekebilecek bir kilidi açtığınız tüm yöntemleri kilitlemeyeceksiniz. Yöntemler asla kilitlenmez, sadece muteks alınmıştır.
Erno

Bu cevabın ifade edilmesinin yanıltıcı olabileceğinden şüpheleniyorum - kilitlemenin yöntemlerin kapsamıyla ilgili hiçbir şey yapması gerekmez - yalnızca bu yöntemlerle erişilen paylaşılan verilerin kapsamı ile ilgilenmelidir . Örnek yöntemi herhangi bir paylaşılan veriye erişemeyebilir (ve dolayısıyla kilitlemeye gerek kalmayabilir), statik paylaşılan verilere erişebilir (dolayısıyla statik kilitlemeye ihtiyaç duyabilir, bunun yerine yeniden düzenleme de iyi bir fikir olabilir), statik için aynı ...
Alexei Levenkov

@AlexeiLevenkov: Kapsamın aslında verilerin statik olup olmadığına göre karar verilmesi gerektiği konusunda haklısınız, ancak yöntemlerin kapsamı da buna göre belirlenmeli, böylece hepsi birbirine uyuyor. Örnek verileri normalde kilitlemeye ihtiyaç duymaz, ancak örnek iş parçacıkları arasında paylaşılıyorsa kilitlemeniz gerekir.
Guffa

28

Bir kilidin kapsamı ve ömrü, kilitlemek istediğiniz 'şeye' bağlı olabilir / bağlı olmalıdır. Statik kilitler çoğunlukla statik şeyleri kilitlemek için kullanılır.


3
Küçük ayrıntı: Kilit statik değildir, kilidi tanımlamak için kullandığınız nesne statiktir. Bir başka küçük ayrıntı: "Eşyaları" kilitlemiyorsunuz.
Guffa

2
Evet, sanırım yanlış "şeyleri" kilitlemeye çalışırsak, çok büyük ve güçlü olabilirler ve bir gün kaçabilirler.
ProfK

12
@Guffa Bu tuhaf, yukarıdaki bir yorumda haklı olarak şunu söyledin: "İşleri çok karmaşık hale getiriyorsun," şimdi bunu söylemeden önce 1 dakika görüyorum, işleri aşırı karmaşıklaştırıyorsun :)
Nicholas Petersen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.