tags:

views:

530

answers:

3

After reading about using react in an actor, I thought reacts would share the same thread when there weren't multiple reacts pending, but it isn't the case:

import scala.actors.Actor
import scala.actors.Actor._


class SleepyReactor extends Actor {
    def act() {
     loop {
      react {
       case x => {
        println("reacting to %s on thread %s".
                             format(x, Thread.currentThread.getName))
        Thread.sleep(1000)
        println("done with " + x)
       }
      }
     }
    }
}
val sleepyOne = new SleepyReactor
sleepyOne.start
sleepyOne ! "first" // runs on thread-5

// wait until completion

sleepyOne ! "second" // runs on thread-3

Can someone explain why these are running on different threads and when a new thread will be created for an actor with react?

I read somewhere react is event based, and I took that to mean that "react actors" shared a thread and if one was "reacting" the other "react actors" would be queued until the first was done. I now think I am wrong. How does this work, and how is it different than receive?

Thank you very much for any help.

+2  A: 

The scheduler library uses a thread pool to control execution of the actors. I don't know the specifics of the logic it uses, but, to me, it would seem natural to expect it to:

  • Initialize with more than one thread in the pool, as multithreaded applications are very likely to use more than one thead.

  • Select the thread to be used with a waiting actor in a queue-like manner -- threads are freed to the end of the queue, and acquire from the beginning of the queue.

Also, I assume some threads are used to handle the scheduling itself as well as message passing.

Daniel
+3  A: 

It is true that for a pure event-based actor, its reacting code runs on the same thread as message sending code.

But in Scala, since it's not desirable to block a thread when an actor calls a blocking operation inside its react code and to unify event-based and thread-based actors(being able to compose them), both type of actors uses the same thread pool but the thread-based actors get their own threads whereas event-based actors shares threads based on a task queue. For details, please see Actors that Unify Threads and Events by Philipp Haller and Martin Odersky

Walter Chang
+3  A: 

Don't assume a separate thread per Actor. The Scala machinery creates a pool of worker threads and only grows that pool if the size of 'blocked' Actors is greater than the pool size. When your actor calls receive, it's in a blocked state until it receives its message.

arcticpenguin