.Class için Java ile Senkronize Blok


Yanıtlar:


144

Snippet synchronized(X.class) , sınıf örneğini bir monitör olarak kullanır. Yalnızca bir sınıf örneği olduğu için (çalışma zamanında sınıf meta verilerini temsil eden nesne) bu blokta bir iş parçacığı olabilir.

İle synchronized(this)bloğun örneği tarafından korunuyor. Her örnek için bloğa yalnızca bir iş parçacığı girebilir.

synchronized(X.class)blokta tam olarak bir İş parçacığı olduğundan emin olmak için kullanılır. synchronized(this)örnek başına tam olarak bir iş parçacığı olmasını sağlar. Bu, blok iş parçacığındaki gerçek kodu güvenli hale getirirse, uygulamaya bağlıdır. Eğer mutate ise sadece örneğin synchronized(this)durumu yeterlidir.


6
"örnek olduğu kadar çok evre bloğa girebilir", ikinci formun doğru olmayan bir semafor gibi davrandığını ima eder. Şöyle bir şey söylemelisiniz: "senkronize (bu), sınıfın belirli bir örneği için yalnızca bir iş parçacığının bloğa girebilmesini sağlar".
liwp

Düzeltildi. Bunu söylemek niyetindeydim.
Thomas Jung

2
örnek vs sınıf örneği nedir?
Weishi Zeng

Öyleyse, statik bir yönteminiz varsa ve tüm gövdesini senkronize etmek istemiyorsak, o zaman senkronize ettik (bu) iyi değil, bunun yerine senkronize (Foo.class) uygundur. Bu doğru mu?
krupal.agile

84

Diğer cevaplara eklemek için:

static void myMethod() {
  synchronized(MyClass.class) {
    //code
  }
}

eşdeğerdir

static synchronized void myMethod() {
  //code
}

ve

void myMethod() {
  synchronized(this) {
    //code
  }
}

eşdeğerdir

synchronized void myMethod() {
  //code
}

12
İlk iki örneğin "statik" anahtar kelimesine sahip olduğunu anlamak için ikinci bir okumayı yaptım. Sadece bunu görmüş ve kaçırmış olabilecek diğer kişilere işaret ediyorum. Statik anahtar kelime olmadan ilk iki örnek aynı olmazdı.
kurtzbot

1
Bu örnekler eşdeğer DEĞİLDİR! Senkronize yöntemler, bir iş parçacığı yöntemleri çağırmaya çalıştığında bir delik olarak "senkronize edilir". Öte yandan bloklar, birden fazla iş parçacığından çalıştırılabilen üstlerinde ve altlarında koda sahip olabilir. Sadece blok içinde senkronize olurlar! Bu aynı değil!
JacksOnF1re

public static Singleton getInstance () {if (örnek == null) {senkronize (Singleton.class) {örnek = new Singleton (); }} dönüş örneği; }
JacksOnF1re

2
Bütün mesele orada olmasıdır olduğu dışında hiçbir kod synchronizedblokları. Bu onları eşdeğer kılar. Bir örneği değiştirirseniz, aslında artık aynı değillerdir.
Jorn

23

Hayır, ilki, sınıf tanımına kilitlenecek, MyClasstüm örneklerine değil. Ancak, bir örnekte kullanılırsa bu, tek bir sınıf tanımını paylaştıkları için diğer tüm örnekleri etkin bir şekilde engelleyecektir.

İkincisi, yalnızca geçerli örnekte kilitlenecektir.

Bunun nesnelerinizi güvenli hale getirip getirmediğine gelince, bu çok daha karmaşık bir sorudur - kodunuzu görmemiz gerekir!


1
evet, MyClass.class herhangi bir statik değişken olabilir ve aynı etkiye sahip olabilir.
pstanton

0

Evet olacak (herhangi bir senkronize blok / fonksiyonda).

Birkaç gündür bu soruyu kendime merak ediyordum (aslında kotlin'de). Sonunda iyi bir açıklama buldum ve paylaşmak istiyorum:

Sınıf düzeyi kilidi, çalışma zamanında sınıfın tüm kullanılabilir örneklerinden herhangi birinde birden çok iş parçacığının senkronize bloğa girmesini engeller. Bu, çalışma zamanında 100 DemoClass örneği varsa, o zaman yalnızca bir iş parçacığı bir seferde herhangi bir örnekte demoMethod () çalıştırabilir ve diğer tüm örnekler diğer iş parçacıkları için kilitlenir.

Statik veri iş parçacığını güvenli hale getirmek için her zaman sınıf düzeyinde kilitleme yapılmalıdır. Statik anahtar kelimenin yöntemlerin verilerini sınıf düzeyiyle ilişkilendirdiğini bildiğimiz için, sınıf düzeyinde yapmak için statik alanlarda veya yöntemlerde kilitlemeyi kullanın.

Artı neden .class . Bunun nedeni .classşuna benzer herhangi bir statik sınıf değişkenine eşdeğer olmasıdır:

private final static Object lock = new Object();

burada kilit değişkeni adı sınıf ve tür Sınıf <T>

Daha fazlasını okuyun: https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/

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.