Scala'da, AnyRef üzerinde AnyRef'i genişleten herhangi bir nesneyle senkronize etmenizi sağlayan senkronize bir yöntem var. Ancak, AnyRef üzerinde özet ve ben scala kaynağına grepping çalıştı nasıl anlayamadım. Java'daki senkronize anahtar sözcüğünü kullanarak çalışır gibi görünüyor. Bu dava mı?AnyRef'te senkronize yöntem nasıl uygulanır?
cevap
1) AnyRef.synchronized
, kaynak kodunda bulunmayan, ancak derleyicinin her başlatılırken derleyicinin sembol tablosuna enjekte edilen sihirli bir yöntemdir: Definitions.scala. Bu arada, bir dizi sihirli yöntem ve sınıf var (Definitions.scala). Bir yöntem this.synchronized
sarılı ise
2), ambalaj bırakılır ve yöntem dahili sonra JVM `ACC_SYNCHRONIZED yöntem erişim bayrağı (GenASM.scala) eşlenen bir SYNCHRONIZED
bayrağı (UnCurry.scala) ile açıklandı. synchronized
için
3) Diğer aramalar üzerine eşlemlenmektedir sonra monitorenter/monitorexit (GenICode.scala #1, GenICode.scala #2) içine indirilir arka uç ilkel SYNCHRONIZED
(backend/ScalaPrimitives.scala).
Derleyiciyi kalpten tanıyan Eugene'nin yanıtına eklemek için, burada küçük bir scala konsol oturumu var.
Alt satır: oluşturulan kod, java'da alacağınızla tam olarak aynıdır. Senkronize edilmiş {...} için bir kapanma yoktur ve bir yöntem çağrısı bile yoktur. Denemenin başlangıcında bir monitör bayt kodu (3) ve her ikisi de normal çıkışta (9), çıkış çıkışında (12) bir monitorexit olduğu bir deneyin/yakalayın. Bu nedenle, scala'da senkronize olarak kullanıldığında vs java'da kullanıldığında hiçbir ek yük bulunmamaktadır.
Çoğu insan, her nesnede tehlikeli düzeyde düşük düzeyli iş parçacığı senkronizasyonu oluşturmanın genellikle yalnızca java uyumluluğu için yapılan kötü bir fikir olarak kabul edildiğini kabul eder.
scala> class Test { def test { this.synchronized { } } }
defined class Test
scala> :javap -c Test
Compiled from "<console>"
public class Test extends java.lang.Object implements scala.ScalaObject{
public void test();
Code:
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: getstatic #12; //Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
7: pop
8: aload_1
9: monitorexit
10: return
11: aload_1
12: monitorexit
13: athrow
Exception table:
from to target type
4 10 11 any