2009-08-16 24 views
6

İki "ifade" arasındaki gerçek (anlamsal) farkı anlamıyorum.
"Döngü" "tepki" ve "(true)" ile "al" arasına sığar, çünkü "tepki" geri dönmez ve "döngü" tekrar tekrar bedenini çağıran bir işlevdir. Kaynaklardan düştüğüm budur - kullanılan "ve" "ile gerçekten tanıdık değilim. "Al", havuzdan bir Thread'i engeller, "tepki ver" değil. Bununla birlikte, "tepki verme" için, işlevin eklenebileceği bir İplik araştırılır.while (true) ile loop arasındaki fark nedir?

Soru şu ki: "alma" ile "döngü" yi neden kullanamıyorum? Aynı zamanda "while (true)" varyantından farklı (ve daha iyi!) Davranıyor gibi gözüküyor, en azından bu bir profilerde gözlemlediğim şey. Daha da garip, "-Dactors.maxPoolSize = 1 -Dactors.corePoolSize = 1" ile "ping-pong" ("true (doğru)" ve "al" komutlarını hemen çağırmak (beklediğim şey) - "döngü" ve "alma", sorunsuz çalışır - tek bir Konuda - bu nasıl?

Teşekkürler!

+0

Tepki ve alma arasındaki fark, alıcı bir tepki verirken bir iplik alırken "biraz daha akıllı" olur ve neeeded – Schildmeijer

+1

bir tane kaplar. Teşekkürler, ben soruya bilgi ekledim - ancak, aradaki farkı açıklamıyor (doğru) ve döngü ve kullanılan kullanım şekli: alma-> (true), tepki-> döngüsü. Benim için alma-> döngüsü de çalışırdı ve daha da iyiydi ... – Ice09

cevap

2

yöntem loop nesne Actor tanımlanır:

private[actors] trait Body[a] { 
    def andThen[b](other: => b): Unit 
} 

implicit def mkBody[a](body: => a) = new Body[a] { 
    def andThen[b](other: => b): Unit = self.seq(body, other) 
} 

/** 
* Causes <code>self</code> to repeatedly execute 
* <code>body</code>. 
* 
* @param body the code block to be executed 
*/ 
def loop(body: => Unit): Unit = body andThen loop(body) 

Bu kafa karıştırıcı olduğunu, ancak ne olur döngü ({ ve } arasındaki şey) sonra gelen blok metodu seq geçirilir olmasıdır ilk argüman olarak ve bu bloğa sahip yeni bir döngü ikinci argüman olarak iletilir. yöntemin seq gelince

, özelliği Actor yılında, buluruz:

private def seq[a, b](first: => a, next: => b): Unit = { 
    val s = Actor.self 
    val killNext = s.kill 
    s.kill =() => { 
    s.kill = killNext 

    // to avoid stack overflow: 
    // instead of directly executing `next`, 
    // schedule as continuation 
    scheduleActor({ case _ => next }, 1) 
    throw new SuspendActorException 
    } 
    first 
    throw new KillActorException 
} 

Yani, yeni döngü bir cinayetten sonra bir sonraki eylem için planlanan, daha sonra blok bir istisna daha sonra idam ve alır KillActorException türü atılır, bu döngü tekrar yürütülmesine neden olur.

Yani, bir while döngü o hiçbir istisna atar gibi, çok daha hızlı bir loop olduğunu gerçekleştiren Öte yandan hiçbir zamanlama vb zamanlayıcı bir loop iki yürütmeler arasında başka bir şey planlamak için fırsat olur mu.

+0

Bu, döngü ile sadece bir Thread'de (zamanlamadan dolayı) 2 farklı "almayı" mümkün kılan son neden (son cümlesi) mi? – Ice09

+0

Evet, ancak, daha sonra, iş parçacığı kendinize saklamak istemiyorsanız yanıtı almaktan daha hızlıdır. –

4

while ve loop arasında önemli bir fark whileaynı iplik oluştuğu döngü yineleme kısıtlar olmasıdır. loop yapısı (Daniel tarafından açıklandığı gibi), aktör alt sisteminin tepkilerini seçtiği herhangi bir iş parçacığına davet etmesini sağlar.

Bu nedenle, tek bir iplik receive bağları while (true) içinde bir oyuncu bir kombinasyonunu kullanarak verir. loop ve reactöğelerini kullanarak, tek bir iş parçacığına tek bir iş parçacığı üzerinde destek sağlamanıza olanak tanır.

+0

Tamam, yani döngü ile almayı birleştirirsek (söz konusu kombinasyon hangisi ise), aynı zamanda farklı ileti dizilerinde de çalıştırılabilir. Açıklamalarınızda, (t) ve reaksiyonun kombinasyonunun hiç bir anlam ifade etmeyeceğini anlıyorum (tepkiyi geri vermemek yüzünden), ancak döngü/tepki fikrini tam olarak anlamıyorum. – Ice09

+0

Eğer aldığınız kaynağa bakarsanız, o zamanki parçacığı engelleyecektir. –

+0

("suspendActor" yöntemindedir ve "alma" denir) –

İlgili konular