2016-04-04 23 views
0

Uzun tip bir id olan bir FooClass kullandığınızı varsayalım:Oluşturulan bir anahtara göre iş parçacıkları arasında karşılıklı dışlama için Java'da genel bir çözüm var mı?

public class FooClass { 
    long id; 
} 

bir yöntem yoktur benzer imzayla ne olursa olsun sınıfı:

public void shouldBeSynchronizedForAFooClassId(long fooClassId) { 
    //does something 
} 

yapabileceğim Ne:

  • Yöntemi senkronize edebilirim, ancak FooClass ve id 1'den beri gereksiz bir darboğazdır ve id ile FooClass 2 problemsiz paralel çalışabilir.
  • Ben kimliğe sahip bir dize oluşturmak ve yapmak bunun bir stajyer(), ve bunu üzerinde senkronize olabilir olabilir Longs ile ilgili
  • Senkronizasyon da iyi bir fikir değildir (bu fikrini sevmiyorum).
  • Map numaralı anahtarı, anahtar olarak kimliği ve izlenen Object değeri olarak oluşturabilirim. Bu durumda, izlenen Nesneleri artık herhangi bir iş parçacığı tarafından kullanılmadığı anda temizleyebilmek için, aynı izlenen Nesneyi kullanarak iş parçacıklarının sayısını kaydetmeye çalışmak zorundayım.

    • (yukarıda Uzun ile benim sonbaharda) türüyle generized bir LockManager ya da her türlü, olabilir:
    • düşündüğümden

    gibi bir hazır çözüm bulunmalıdır. Gerekirse, monitör nesnesinin oluşturulması da dahil olmak üzere, karşılıklı dışlanmayı kapsülleyecek ve daha sonra kaldıracak bir runSafely (Runnable run) yöntemi sağlayabilir. Tabii ki bu runSafely içinde id almak zorunda.

Bu kitaplıktaki kutunun dışında bir şey var mı? İhtiyacınız

+1

FooClass örneğinin kendisini eşzamanlayamıyor musunuz (as kimliği eşlemelerini tek bir ilgili FooClass örneğiyle varsayarak)? Aksi takdirde, Guava'nın Çizgili sayfasına bakın: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/Striped.html –

+0

@JBNizet fooClass üzerinde senkronizasyon yardımcı değildir, çünkü birkaç FooClass örnekleri JVM'de bulunabilir (kalıcılık katmanıyla yüklenir, farklı oturumlar tarafından değiştirilir veya kullanılır) –

+1

Sonra Guava'nın Çizgisi muhtemelen sizin istediğiniz gibi olabilir. –

cevap

1

Bildiğim kadarıyla, JDK'de karşılaştığınız soruna hazır bir çözüm yok.

Ancak, Guava'nın, istediğiniz her şeyi yapan Striped vardır. Kimlik başına bir kilitle değil, kimliklerin "şerit" başına bir kilitle ilişkilendirilir. Bu çekişmeyi önlemek için yeterli olmalıdır.

1

araçları kullanılabilir ancak ID tanımladığınız bir sınıf nerede olduğunu çözüm kendiniz, mesela a map

+0

Basit bir Kilitler haritasıyla, hiçbir iş parçacığının ihtiyacı olmadığında kilitleri kaldırmam gerekiyor. –

0

yerine long idReentrantLocks nedeniyle, ID id; olabilir montaj gerekecek. Daha sonra id nesnesini kilitleyebilirsiniz.

Kimlik sınıfınız sayısal bir değere veya uygun bulduğunuz diğer özelliklere sahip olabilir.

+0

Bir ID sınıfım varsa, içte aynı uzun kimliğe sahip iki kimlik kimliğine sahip olmanıza yardımcı olmaz. Aynı sayısal kimlik için iki nesne. –

+0

@ GáborLipták, bunu yapmayan bir kod yazacağınızı varsayalım. Bir 'ID' sınıfını tanımlama önerim, 'FooClass' örneklerine kimlik atamak sorununu çözmek anlamına gelmiyordu: Sorunu çözmek gerekiyordu,' uzun 'kilitleyebileceğiniz bir şey değil. –

+0

Bu şekilde, artık kullanılmayan örneklerin temizlenmesi sorununda sona eren tek bir ID'den kimlikler oluşturmalı ve kaydetmeliyim. Yukarıdaki soruma dair yorumumda yazmış olduğum gibi, FooClass örnekleri de uygulamanın içinde birkaç yerde oluşturuluyor. –