synchronized
Anahtar kelimenin kullanımı ve önemi ile ilgili bazı sorularım var .
synchronized
Anahtar kelimenin önemi nedir ?- Yöntemler ne zaman olmalı
synchronized
? - Programlı ve mantıksal olarak ne anlama geliyor?
synchronized
Anahtar kelimenin kullanımı ve önemi ile ilgili bazı sorularım var .
synchronized
Anahtar kelimenin önemi nedir ?synchronized
?Yanıtlar:
synchronized
Anahtar kelime okuma ve aynı değişkenler, nesneler ve kaynaklara yazma farklı konuları ile ilgili. Bu Java'da önemsiz bir konu değil, ancak Sun'ın bir alıntısı:
synchronized
yöntemler, iş parçacığı etkileşimini ve bellek tutarlılığı hatalarını önlemek için basit bir strateji sağlar: bir nesne birden fazla iş parçacığında görünürse, o nesnenin değişkenlerine tüm okuma veya yazma işlemleri senkronize yöntemlerle yapılır.
Çok, çok küçük bir özetle: Aynı 'kaynağa' okuma ve yazma yapan iki iş parçanız varsa, adlı bir değişken söyleyin foo
, bu iş parçacıklarının değişkene atomik bir şekilde erişmesini sağlamanız gerekir. synchronized
Anahtar kelime olmadan, iş parçanız 1, yapılan iş parçacığı 2'yi değiştiremez foo
veya daha da kötüsü, yalnızca yarısı değiştirilebilir. Mantıksal olarak beklediğiniz bu olmaz.
Yine, bu Java'da önemsiz olmayan bir konudur. Daha fazla bilgi edinmek için burada SO ve Interwebs ile ilgili konuları inceleyin:
"Brian Goetz" adı beyninizdeki "eşzamanlılık" terimi ile kalıcı olarak ilişkilendirilene kadar bu konuları araştırmaya devam edin .
Sanırım yeterince teorik açıklama yaptık, bu yüzden bu kodu düşünün
public class SOP {
public static void print(String s) {
System.out.println(s+"\n");
}
}
public class TestThread extends Thread {
String name;
TheDemo theDemo;
public TestThread(String name,TheDemo theDemo) {
this.theDemo = theDemo;
this.name = name;
start();
}
@Override
public void run() {
theDemo.test(name);
}
}
public class TheDemo {
public synchronized void test(String name) {
for(int i=0;i<10;i++) {
SOP.print(name + " :: "+i);
try{
Thread.sleep(500);
} catch (Exception e) {
SOP.print(e.getMessage());
}
}
}
public static void main(String[] args) {
TheDemo theDemo = new TheDemo();
new TestThread("THREAD 1",theDemo);
new TestThread("THREAD 2",theDemo);
new TestThread("THREAD 3",theDemo);
}
}
Not: synchronized
önceki iş parçacığının yürütülmesi bitmediği sürece bir sonraki iş parçacığının yöntem testine () çağrısını engeller. Konular bu yönteme birer birer erişebilir. olmadansynchronized
Tüm aynı anda bu yönteme erişebilirsiniz.
Bir iş parçacığı, nesnenin eşitlenmiş 'test' yöntemini çağırdığında (burada nesne, 'TheDemo' sınıfının bir örneğidir), bu nesnenin kilidini alır, herhangi bir yeni iş parçacığı, önceki iş parçacığı kadar aynı nesnenin HERHANGİ bir eşitlenmiş yöntemini çağıramaz kilidi almış olan kilidi serbest bırakmaz.
Sınıfın herhangi bir statik senkronize yöntemi çağrıldığında da benzer bir şey olur. İş parçacığı sınıfla ilişkili kilidi alır (bu durumda o sınıfın bir örneğinin statik olmayan eşitlenmiş yöntemi herhangi bir iş parçacığı tarafından çağrılabilir, çünkü bu nesne düzeyi kilidi hala kullanılabilir). Sınıf düzeyi kilidi, şu anda kilidi tutan iş parçacığı tarafından serbest bırakılmadığı sürece, başka hiçbir iş parçacığı, sınıfın statik senkronize yöntemini çağıramaz.
Senkronize edilmiş çıkış
THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9
Senkronize olmayan çıkış
THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
synchronized
, ancak bellek tutarlılığı yok sayılır.
synchronized
Anahtar birden fazla ilmek kodu veya nesnenin bir blok eş zamanlı erişimi engeller. Tüm yöntemleri Hashtable
vardır synchronized
, bu nedenle aynı anda yalnızca bir iş parçacığı yürütebilir.
synchronized
Gibi kurguları kullanırken HashMap
, tutarlılık hatalarını önlemek için kodunuzda iş parçacığı güvenliği özellikleri oluşturmanız gerekir.
synchronized
çok iş parçacıklı bir ortamda, synchronized
yöntem (ler) / blok (lar) a sahip bir nesnenin iki iş parçacığınınsynchronized
kod yöntemlerine / kod bloklarına aynı anda . Bu, bir iş parçacığı başka bir iş parçacığı güncelleştirirken okuyamayacağı anlamına gelir.
Bunun yerine ikinci iş parçacığı, ilk iş parçacığı yürütme işlemini tamamlayana kadar bekler. Genel gider hızdır, ancak avantaj verilerin tutarlılığı garanti edilir.
Uygulamanız tek iş parçacıklıysa, synchronized
bloklar fayda sağlamaz.
synchronized
Anahtar kelime yöntemi girerken (statik bir yöntem olmadığı sürece verilen nesne örneğin) tek iplik aynı anda yöntemi yürütebileceği böylece, bir kilit elde etmek için bir iş parçacığı neden olur.
Bu sık sık sınıf iş parçacığı güvenli yapma denir, ama bunun bir örtmece olduğunu söyleyebilirim. Senkronizasyonun Vector öğesinin dahili durumunu bozulmaya karşı koruduğu doğru olsa da, bu genellikle Vector kullanıcısına çok fazla yardımcı olmaz.
Bunu düşün:
if (vector.isEmpty()){
vector.add(data);
}
İlgili yöntemler senkronize olsa da, ayrı ayrı kilitlendikleri ve kilidinin açıldığı için maalesef iki zamanlanmış iş parçacığı iki öğeli bir vektör oluşturabilir.
Dolayısıyla, uygulama kodunuzda da senkronize etmeniz gerekir.
Yöntem düzeyinde senkronizasyon a) ihtiyacınız olmadığında pahalı olduğu ve b) senkronizasyon gerektiğinde yetersiz olduğu için, artık senkronize edilmemiş değiştirmeler (Vector durumunda ArrayList) vardır.
Daha yakın zamanlarda, çoklu iş parçacığı sorunlarıyla ilgilenen bir dizi akıllı yardımcı programla eşzamanlılık paketi yayınlandı.
Java'da senkronize edilen anahtar kelime, iş parçacığı güvenliği ile ilgilidir, yani birden fazla iş parçacığı aynı değişkeni okuduğunda veya yazdığında.
Bu doğrudan (aynı değişkene erişerek) veya dolaylı olarak (aynı değişkene erişen başka bir sınıf kullanan bir sınıf kullanarak) olabilir.
Senkronize anahtar kelime, birden çok iş parçacığının aynı değişkene güvenli bir şekilde erişebileceği bir kod bloğu tanımlamak için kullanılır.
Sözdizimi açısından, synchronized
anahtar kelime Object
parametresi olarak ( kilit nesnesi olarak adlandırılır ) alır ve ardından a gelir { block of code }
.
Yürütme bu anahtar sözcükle karşılaştığında, geçerli iş parçacığı kilit nesnesini "kilitlemeye / almaya / sahiplenmeye" (seçiminizi yapmaya) ve kilit alındıktan sonra ilişkili kod bloğunu yürütmeye çalışır.
Senkronize kod bloğundaki değişkenlere yapılan tüm yazma işlemlerinin, aynı kilit nesnesini kullanarak senkronize bir kod bloğu içinde benzer şekilde kod yürüten diğer tüm iş parçacıkları tarafından görüleceği garanti edilir .
Bir seferde yalnızca bir iş parçacığı kilidi tutabilir, bu sırada aynı kilit nesnesini almaya çalışan diğer tüm iş parçacıkları bekler (yürütülmelerini duraklatır). Yürütme senkronize kod bloğundan çıktığında kilit serbest bırakılır.
synchronized
Bir yöntem tanımına anahtar kelime eklemek , kilit nesnesi this
(örneğin yöntemler) ve ClassInQuestion.getClass()
(sınıf yöntemleri için ) olmak üzere senkronize edilmiş bir kod bloğuna sarılmış olan tüm yöntem gövdesine eşittir .
- Örnek yöntemi, static
anahtar kelimesi olmayan bir yöntemdir .
- Sınıf yöntemi static
anahtar kelimeye sahip bir yöntemdir .
Senkronizasyon olmadan, okumaların ve yazmaların hangi sırayla gerçekleşeceği garanti edilmez ve büyük olasılıkla değişkeni çöple birlikte bırakır.
(Örneğin, bir değişken, bir iş parçacığı tarafından yazılan bitlerin yarısı ve başka bir iş parçacığı tarafından yazılan bitlerin yarısı ile değişebilir ve değişkeni, iş parçacıklarının hiçbirinin yazmaya çalışmadığı, ancak her ikisinin birleşik karmaşası şeklinde bırakabilir.)
Başka bir iş parçacığı okumadan önce bir iş parçacığında bir yazma işlemini tamamlamak yeterli değildir, çünkü donanım değişkenin değerini önbelleğe almış olabilir ve okuma iş parçacığı, yazılanlar yerine önbelleğe alınmış değeri görür o.
Bu nedenle Java'nın durumunda, iş parçacığı hatalarının oluşmamasını sağlamak için Java Bellek Modelini izlemeniz gerekir.
Başka bir deyişle: Senkronizasyon, atom işlemleri veya bunları sizin için davlumbazların altında kullanan sınıfları kullanın.
Kaynaklar
http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Java® Dil Özellikleri, 2015-02-13
Bir futbol sahasında bulabileceğiniz gibi bir tür turnike olarak düşünün. İçeri girmek isteyen insanların paralel buharları var ama turnikede 'senkronize' oluyorlar. Bir seferde yalnızca bir kişi geçebilir. Üstesinden gelmek isteyen herkes yapacak, ama geçene kadar beklemek zorunda kalabilirler.
Senkronize edilen anahtar kelime nedir?
İş parçacıkları öncelikle alanlara ve başvuru alanlarının başvurduğu nesnelere erişimi paylaşarak iletişim kurar. Bu iletişim şekli son derece etkilidir, ancak iki tür hatayı mümkün kılar: iş parçacığı etkileşimi ve bellek tutarlılığı hataları . Bu hataları önlemek için gereken araç senkronizasyondur.
Senkronize bloklar veya yöntemler, iplik girişimini önler ve verilerin tutarlı olduğundan emin olun. Herhangi bir zamanda, sadece bir iş parçacığı bir kilit alarak senkronize bir bloğa veya yönteme ( kritik bölüm ) erişebilir . Diğer diş (ler) kritik bölüme erişmek için kilidin serbest bırakılmasını bekleyecektir .
Yöntemler ne zaman senkronize edilir?
Yöntem synchronized
tanımına veya bildirimine eklediğinizde yöntemler senkronize edilir. Ayrıca belirli bir kod bloğunu bir yöntemle senkronize edebilirsiniz.
Profesyonel dilbilgisi ve mantıksal olarak ne anlama geliyor?
Bu, bir kilit alarak sadece bir iş parçacığının kritik bölüme erişebileceği anlamına gelir . Bu iş parçacığı bu kilidi serbest bırakmadıkça, diğer tüm iş parçacığı kilit almak için beklemek zorunda kalacak. Kritik bölüme girme erişimi yokKilit edinmeden .
Bu bir sihirle yapılamaz. Kritik bölüm (ler) tanımlamak programcının sorumluluğundadır ve buna göre korumak . Java, uygulamanızı korumak için bir çerçeve sağlar, ancak korunacak tüm bölümlerin nerede ve ne olacağı programcının sorumluluğundadır.
Java dokümantasyon sayfasından daha fazla detay
İçsel Kilitler ve Senkronizasyon:
Senkronizasyon, kendinden kilitli veya monitör kilidi olarak bilinen bir dahili varlık etrafında oluşturulur. İçsel kilitler senkronizasyonun her iki yönünde de rol oynar: bir nesnenin durumuna özel erişimin sağlanması ve görünürlük için gerekli olan ilişkiden önce ilişkiler kurulması.
Her nesnenin kendisiyle ilişkilendirilmiş kendinden kilit vardır . Kural olarak, bir nesnenin alanlarına özel ve tutarlı erişime ihtiyaç duyan bir iş parçacığının, nesneye erişmeden önce kendinden kilit alması ve onlarla iş bitince iç kilidi serbest bırakması gerekir.
Bir ipliğin, kilidi edindiği ve kilidi serbest bıraktığı zaman arasında içsel kilide sahip olduğu söylenir. Bir iş parçacığının kendinden kilitlemesine sahip olduğu sürece, başka hiçbir iş parçacığı aynı kilidi alamaz. Diğer iş parçacığı, kilidi almaya çalıştığında engellenir.
Bir iş parçacığı içsel bir kilidi serbest bıraktığında, o eylem ile aynı kilidin daha sonraki herhangi bir edinimi arasında önceden gerçekleşen bir ilişki kurulur.
Yöntemleri senkronize etmenin iki etkisi vardır :
İlk olarak, aynı nesne üzerinde senkronize yöntemlerin iki çağrılması için serpiştirmek mümkün değildir.
Bir iş parçacığı, bir nesne için eşitlenmiş bir yöntem yürütürken, aynı iş parçacığı için eşitlenmiş yöntemleri çağıran diğer tüm iş parçacıkları, ilk iş parçacığı nesne ile yapılana kadar.
İkincisi, senkronize edilmiş bir yöntemden çıkıldığında, otomatik olarak aynı nesne için senkronize edilmiş bir yöntemin herhangi bir çağrılmasıyla önce gerçekleşen bir ilişki kurar.
Bu, nesnenin durumundaki değişikliklerin tüm iş parçacıkları tarafından görülebilir olmasını sağlar.
Senkronizasyon için diğer alternatifleri arayın:
Synchronized normal method
eşdeğeri
Synchronized statement
(bunu kullanın)
class A {
public synchronized void methodA() {
// all function code
}
equivalent to
public void methodA() {
synchronized(this) {
// all function code
}
}
}
Synchronized static method
eşdeğeri Synchronized statement
(sınıfı kullan)
class A {
public static synchronized void methodA() {
// all function code
}
equivalent to
public void methodA() {
synchronized(A.class) {
// all function code
}
}
}
Senkronize ifade (değişken kullanılarak)
class A {
private Object lock1 = new Object();
public void methodA() {
synchronized(lock1 ) {
// all function code
}
}
}
İçin synchronized
, biz de var Synchronized Methods
ve Synchronized Statements
. Ancak, Synchronized Methods
buna benzer, Synchronized Statements
bu yüzden sadece anlamamız gerekiyor Synchronized Statements
.
=> Temel olarak, sahip olacağız
synchronized(object or class) { // object/class use to provides the intrinsic lock
// code
}
İşte anlamaya yardımcı olan 2 düşünce synchronized
intrinsic lock
kendisiyle bir ilişkisi vardır.synchronized statement
, o nesne intrinsic lock
için otomatik olarak alınır synchronized statement's
ve yöntem döndüğünde onu serbest bırakır. Bir iş parçacığı bir sahip olduğu sürece intrinsic lock
, başka bir iş parçacığı aynı kilit => iş parçacığı güvenli elde edemez .=> Bir thread A
invokes synchronized(this){// code 1}
=> sahip olduğu tüm blok kodu (sınıf içi) synchronized(this)
ve hepsi aynı synchronized normal method
(sınıf içi) kilitlidir çünkü aynı kilit. thread A
Kilidi açtıktan sonra yürütülür ("// kod 1" bitti).
Bu davranış synchronized(a variable){// code 1}
veya biçimine benzer synchronized(class)
.
AYNI KİLİT => kilit (hangi yönteme veya hangi ifadelere bağlı değil?)
synchronized statements
Daha uzatılabilir olduğu için tercih ederim . Örneğin, gelecekte, yöntemin yalnızca bir kısmını senkronize etmeniz gerekir. Örnek olarak, 2 senkronize yönteminiz vardır ve birbiriyle ilişkili değildir , ancak bir iş parçacığı bir yöntemi çalıştırdığında, diğer yöntemi engeller (kullanım tarafından önlenebilir synchronized(a variable)
).
Ancak, senkronize yöntem uygulamak basit ve kod basit görünüyor. Bazı sınıflar için, yalnızca 1 senkronize yöntem veya sınıftaki birbiriyle ilişkili tüm senkronize yöntemler => synchronized method
kodu daha kısa ve anlaşılması kolay hale getirmek için kullanabiliriz
(çok fazla ilgisi yoktur synchronized
, nesne ve sınıf arasındaki fark veya hiç statik olmayan ve statik).
synchronized
veya normal yöntem veya synchronized(this)
veya synchronized(non-static variable)
her nesne örneği temel eşitlenir. synchronized
veya statik yöntemi veya synchronized(class)
veya synchronized(static variable)
bunun sınıfına tabanını senkronize olacakhttps://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
Umarım yardımcı olur
İşte Java Dersleri'nden bir açıklama .
Aşağıdaki kodu göz önünde bulundurun:
public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() { return c; } }
eğer
count
bir örneğidirSynchronizedCounter
, daha sonra senkronize bu yöntemleri yapma iki etkiye sahiptir:
- İlk olarak, aynı nesne üzerinde senkronize yöntemlerin iki çağrılması için serpiştirmek mümkün değildir. Bir iş parçacığı, bir nesne için eşitlenmiş bir yöntem yürütürken, aynı iş parçacığı için eşitlenmiş yöntemleri çağıran diğer tüm iş parçacıkları, ilk iş parçacığı nesne ile yapılana kadar.
- İkincisi, senkronize edilmiş bir yöntemden çıkıldığında, otomatik olarak aynı nesne için senkronize edilmiş bir yöntemin herhangi bir çağrılmasıyla önce gerçekleşen bir ilişki kurar. Bu, nesnenin durumundaki değişikliklerin tüm iş parçacıkları tarafından görülebilir olmasını sağlar.
Eşitlendiğimi anlamak için, derleyicinin yönteminizin etrafına bir monitor.enter ve monitor.exit yazdığı anlamına gelir. Bu nedenle, nasıl kullanıldığına bağlı olarak iş parçacığı güvenli olabilir (yani, sınıfınızın ne yaptığına bağlı olarak threadsafe olmayan senkronize yöntemlerle bir nesne yazabilirsiniz).
Diğer cevapların eksik olması önemli bir husustur: bellek engelleri . İş parçacığı senkronizasyonu temel olarak iki bölümden : serileştirme ve görünürlük. Önemsiz ve son derece önemli bir konu olduğu için (birden çok iş parçacığı tarafından erişilen paylaşılan verileri değiştirirseniz) herkese Google'a "jvm bellek bariyeri" için tavsiyede bulunuyorum. Bunu yaptıktan sonra, açık senkronizasyonu kullanmaktan kaçınmaya yardımcı olan java.util.concurrent paketinin sınıflarına bakmanızı öneririm, bu da programları basit ve verimli tutmaya yardımcı olur, hatta belki de kilitlenmeleri önler.
Böyle bir örnek ConcurrentLinkedDeque'dir . Komut deseni ile birlikte , komutları eşzamanlı kuyruğa doldurarak son derece verimli çalışan iş parçacıkları oluşturmaya izin verir - açık senkronizasyon gerekmez, kilitlenme mümkün değildir, açık uyku () gerekmez, sadece take () diyerek kuyruğu yoklayın.
Kısacası: "bellek senkronizasyonu" bir iş parçacığı başlattığınızda, iş parçacığı sona erdiğinde, geçici bir değişkeni okuduğunuzda, bir monitörün kilidini açtığınızda (senkronize bir blok / işlev bıraktığınızda) dolaylı olarak gerçekleşir . Bu "senkronizasyon" etkiler (bir anlamda "yıkar ") tüm yazılar bu işlemden önce yapılır. Yukarıda belirtilen ConcurrentLinkedDeque durumunda , dokümantasyon "diyor":
Bellek tutarlılığı efektleri: Diğer eşzamanlı koleksiyonlarda olduğu gibi, bir nesneyi bir ConcurrentLinkedDeque içine yerleştirmeden önce bir iş parçacığındaki eylemler, o öğenin başka bir iş parçacığında ConcurrentLinkedDeque öğesine erişilmesi veya bu öğenin kaldırılmasından sonraki eylemlerden önce gerçekleşir.
Bu örtük davranış biraz zararlı bir durumdur, çünkü fazla tecrübesi olmayan çoğu Java programcısı, bu nedenle verilen çok şey alacaktır. Ve sonra Java, farklı bir iş yükünün olduğu üretimde yapılması gerekeni yapmazsa ve aynı zamanda eşzamanlılık sorunlarını test etmek oldukça zorlaştıktan sonra aniden bu iş parçacığına rastlarsınız.
Senkronizasyon, tek bir nesne ile ilişkilendirilirse birden çok iş parçacığının, belirli bir nesne üzerinde senkronize blok kullanıldığında kirli okuma ve yazmayı engelleyebileceği anlamına gelir. Size daha fazla açıklık sağlamak için bir örnek verelim:
class MyRunnable implements Runnable {
int var = 10;
@Override
public void run() {
call();
}
public void call() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
var++;
System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
}
}
}
}
public class MutlipleThreadsRunnable {
public static void main(String[] args) {
MyRunnable runnable1 = new MyRunnable();
MyRunnable runnable2 = new MyRunnable();
Thread t1 = new Thread(runnable1);
t1.setName("Thread -1");
Thread t2 = new Thread(runnable2);
t2.setName("Thread -2");
Thread t3 = new Thread(runnable1);
t3.setName("Thread -3");
t1.start();
t2.start();
t3.start();
}
}
İki MyRunnable sınıf nesnesi oluşturduk; runnable1 iş parçacığı 1 ve iş parçacığı 3 & runnable2 yalnızca iş parçacığı 2 ile paylaşılıyor. Şimdi t1 ve t3 senkronize kullanılmadan başladığında, hem diş 1 hem de 3'ün aynı anda diş 2 için var değerini etkilediğini öneren PFB çıktısı, var'ın kendi belleğine sahip olduğunu gösterir.
Without Synchronized keyword
Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -2 var value 12
Current Thread Thread -2 var value 13
Current Thread Thread -2 var value 14
Current Thread Thread -1 var value 12
Current Thread Thread -3 var value 13
Current Thread Thread -3 var value 15
Current Thread Thread -1 var value 14
Current Thread Thread -1 var value 17
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 18
Eşzamanlı olarak, iş parçacığı 1'in tüm senaryolarda tamamlanmasını bekleyen iş parçacığı 3. Biri iş parçacığı 1 ve iş parçacığı 3 tarafından paylaşılan runnable1 üzerinde ve diğeri yalnızca iş parçacığı 2 tarafından paylaşılan runnable2 üzerinde iki kilit edinilmiş.
Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18
senkronize basit, hiçbir iş parçacığının bloğa / yönteme aynı anda erişemeyeceği anlamına gelir. Bir sınıfın herhangi bir bloğunun / yönteminin senkronize edildiğini söylediğimizde, aynı anda yalnızca bir iş parçacığına erişilebileceği anlamına gelir. Dahili olarak ona erişmeye çalışan iş parçacığı önce o nesne üzerinde bir kilit alır ve bu kilit mevcut olmadığı sürece, başka hiçbir iş parçacığı sınıfın o örneğinin senkronize yöntemlerinden / bloklarından hiçbirine erişemez.
Başka bir iş parçacığının, eşitlenecek şekilde tanımlanmamış aynı nesnenin bir yöntemine erişebileceğini unutmayın. Bir iş parçacığı arayarak kilidi açabilir
Object.wait()
synchronized
Java'daki blok çoklu kullanımda bir monitördür. synchronized
aynı nesne / sınıf ile blok sadece tek bir iş parçacığı tarafından yürütülebilir, diğerleri bekliyor. race condition
Birkaç iş parçacığı aynı değişkeni güncellemeye çalıştığında duruma yardımcı olabilir (ilk adım volatile
Hakkında'yı kullanmaktır )
Java 5
synchronized
destekleyerek genişletildi happens-before
[Hakkında]
Bir monitörün kilidinin açılması (senkronize blok veya yöntem çıkışı) - aynı monitörün her sonraki kilidinden (senkronize blok veya yöntem girişi) önce gerçekleşir.
Bir sonraki adım java.util.concurrent