2009-08-16 65 views
6

Tôi không nhận được sự khác biệt thực tế (ngữ nghĩa) giữa hai "biểu thức".
Người ta nói "vòng lặp" phù hợp với "phản ứng" và "trong khi (đúng)" để "nhận", bởi vì "phản ứng" không trả về và "vòng lặp" là một hàm gọi cơ thể một lần nữa. đây là những gì tôi khấu trừ từ các nguồn - Tôi không thực sự quen thuộc với "andThen" được sử dụng). "Nhận" khối một Thread từ hồ bơi, "phản ứng" thì không. Tuy nhiên, đối với "phản ứng" một Thread được tra cứu có thể gắn vào hàm nào.Sự khác biệt giữa while (true) và loop là gì?

Vì vậy, câu hỏi đặt ra là: tại sao tôi không thể sử dụng "vòng lặp" bằng "nhận"? Nó cũng có vẻ hành xử khác nhau (và tốt hơn!) So với biến thể "while (true)", ít nhất đây là những gì tôi quan sát trong một profiler. Thậm chí còn lạ lẫm hơn khi gọi một bóng bàn với "-Dactors.maxPoolSize = 1 -Dactors.corePoolSize = 1" với khối "while (true)" và "receive" ngay lập tức (đó là những gì tôi mong đợi) - tuy nhiên, với "vòng lặp" và "nhận", nó hoạt động mà không có vấn đề - trong một Thread - làm thế nào của điều này?

Cảm ơn!

+0

iirc sự khác biệt giữa phản ứng và nhận là nhận được occuppies một chủ đề trong khi phản ứng là chút "thông minh hơn" và chiếm một khi neeeded – Schildmeijer

+1

Cảm ơn, tôi thêm vào thông tin cho câu hỏi - tuy nhiên, nó không giải thích sự khác biệt trong khi (true) và vòng lặp và mẫu sử dụng đi: receive-> while (true), react-> loop. Đối với tôi, receive-> loop cũng sẽ hoạt động và thậm chí tốt hơn ... – Ice09

Trả lời

2

Phương pháp loop được định nghĩa trong đối tượng Actor:

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) 

Đây là khó hiểu, nhưng những gì xảy ra là các khối đó đưa ra sau khi vòng lặp (điều giữa {}) được truyền cho phương thức seq là đối số đầu tiên và một vòng lặp mới với khối đó được chuyển làm đối số thứ hai.

Đối với các phương pháp seq, trong đặc điểm Actor, chúng ta thấy:

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 
} 

Vì vậy, vòng lặp mới được lên kế hoạch cho hành động tiếp theo sau một giết, sau đó khối được thực hiện, và sau đó một ngoại lệ loại KillActorException được ném, điều này sẽ làm cho vòng lặp được thực thi lại.

Vì vậy, một vòng lặp while thực hiện nhanh hơn nhiều mà một loop, vì nó ném không có ngoại lệ, không có lịch trình, vv Mặt khác, chức năng lịch được cơ hội để sắp xếp cái gì khác giữa hai hành của một loop.

+0

Đó có phải là lý do cuối cùng (câu cuối cùng) mà làm cho nó có thể sử dụng 2 khác nhau "nhận" trên chỉ có một Thread (do lập kế hoạch) với vòng lặp? – Ice09

+0

Có, nhưng, sau đó, phản ứng nhanh hơn nhận nếu bạn không muốn giữ nguyên chỉ cho chính mình. –

4

Sự khác biệt quan trọng giữa whileloopwhile hạn chế lặp loopxảy ra trong cùng một thread. Cấu trúc loop (như được mô tả bởi Daniel) cho phép hệ thống phụ của diễn viên gọi các phản ứng trên bất kỳ chuỗi nào mà nó chọn.

Do đó, sử dụng kết hợp receive trong phạm vi while (true) liên kết một diễn viên với một chuỗi duy nhất. Sử dụng loopreactcho phép bạn chạy hỗ trợ nhiều diễn viên trên một sợi đơn.

+0

Ok, vì vậy nếu tôi kết hợp vòng lặp và nhận (đó là sự kết hợp trong câu hỏi), cũng nhận được có thể được thực hiện trong các chủ đề khác nhau? Từ lời giải thích của bạn, tôi hiểu rằng sự kết hợp của while (t) và phản ứng sẽ không có ý nghĩa gì cả (do không trả lại phản ứng), nhưng tôi không hoàn toàn hiểu được ý nghĩa của vòng lặp/phản ứng. – Ice09

+0

Tôi nghĩ nếu bạn nhìn vào nguồn nhận được thì nó sẽ chặn luồng hiện tại. –

+0

(Trong phương thức 'suspendActor' và được gọi từ' receive') –

Các vấn đề liên quan