Bu, yapım tamamlanmadan önce, tekil nesneye bir başvuru yayınlanırken Scala'da gerçekleşebilecek doğal bir sorundur. Tamamen oluşturulmadan önce ParCollectionInInitializerTest
nesnesine erişmeye çalışan farklı bir iş parçacığı nedeniyle olur. main
yöntemiyle bir ilgisi yoktur, bunun yerine, main
yöntemini içeren nesneyi başlatmakla ilgili olması gerekir - bunu REPL içinde çalıştırmayı deneyin, ParCollectionInInitializerTest
ifadesini kullanarak yazın ve aynı sonuçları elde edersiniz. Ayrıca, fork-join çalışan iş parçacığının daemon iş parçacığı ile ilgisi yoktur.
Tekil nesneler tembel olarak başlatılır. Her singleton nesnesi sadece bir kez başlatılabilir. Bu, nesneye erişen ilk iş parçacığının (sizin durumunuzda, ana iş parçacığı), nesnenin bir kilidini alması ve sonra onu başlatması gerektiği anlamına gelir. Daha sonra gelen her bir iş parçacığı, ana iş parçacığının nesneyi başlatmasını ve sonunda kilidi serbest bırakmasını beklemek zorundadır. Bu, singleton nesnelerinin Scala'da uygulanma şeklidir.
Sizin durumunuzda, paralel toplama çalışanı iş parçacığı, doSomething
'u çağırmak için tekil nesnesine erişmeye çalışır, ancak ana iş parçacığı nesneyi başlatmayı tamamlayana kadar bunu yapamaz - böylece bekler. Diğer yandan, ana iş parçacığı, tüm çalışan iş parçacığı tamamlandığında, paralel işlem tamamlanana kadar kurucuda bekler - ana iş parçacığı, her zaman tekil için başlatma kilidini tutar. Bu nedenle, bir kilitlenme oluşur.
Aşağıda gösterildiği gibi, ya da sadece parçacığı ile 2.10'dan geleceklerine bu davranışa neden olabilir
:
scala> ParCollection
ve Çoğaltma:
def execute(body: =>Unit) {
val t = new Thread() {
override def run() {
body
}
}
t.start()
t.join()
}
object ParCollection {
def doSomething() { println("Doing something") }
execute {
doSomething()
}
}
yazmak sonra Repl yapıştırın ve asar.
ile ilgili: http: // stackoverflow.com/questions/27549671/nasıl-teşhis-veya-tespit-deadlock-in-java-statik-başlatıcılar – Rich