This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Increase actor thread pool

1 reply
Jesse Eichar
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
I have the following test:

import scala.actors.Actor
import java.net._
import scala.io._

class A(id:Int) extends Actor {
  println("created actor "+id)

  def act = {

    while (true) {
      Source.fromURL(new URL("http://www.wow-europe.com/de/index.xml?rhtml=y"))\
.getLines.foreach( _.length); println("Now download: Actor: "+id) }
  }
}

for( x <- 1 to 300) { new A(x).start() }

while(true) { Thread.sleep(5000) }


-----------------------------------------------------------------------------------
Problem is that only 4 actors will work concurrently.  I changed the download so that it is an expensive calculation but again only 4 actors run concurrently.  Is there a way to configure the number of concurrent actors that can run simultaneously?

Jesse
Philipp Haller
Joined: 2009-01-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Increase actor thread pool

Jesse Eichar wrote:
> I have the following test:
>
> import scala.actors.Actor
> import java.net._
> import scala.io._
>
> class A(id:Int) extends Actor {
> println("created actor "+id)
>
> def act = {
>
> while (true) {
> Source.fromURL(new
> URL("http://www.wow-europe.com/de/index.xml?rhtml=y"))\
> .getLines.foreach( _.length); println("Now download: Actor: "+id) }
> }
> }
>
> for( x <- 1 to 300) { new A(x).start() }
>
> while(true) { Thread.sleep(5000) }
>
>
> -----------------------------------------------------------------------------------
> Problem is that only 4 actors will work concurrently. I changed the
> download so that it is an expensive calculation but again only 4 actors
> run concurrently. Is there a way to configure the number of concurrent
> actors that can run simultaneously?

Normally, arbitrarily many actors can run simultaneously. In your case,
the actors invoke blocking operations, which do not allow freeing the
underlying worker threads of the thread pool.
A special case is `receive` (and `receiveWithin`, etc.), which will
increase the number of threads in the pool if necessary.

Now, to make your example work, you have at least two options:

(1) Globally configure the thread pool size using the JVM properties
`actors.corePoolSize` and `actors.maxPoolSize`. Increase core pool size
to match the number of worker threads you need.

(2) Use a scheduler that will resize the thread pool whenever all worker
threads are blocked, regardless of whether it is `receive`.

In Scala 2.8, option (2) is done as follows:

import scala.actors.{Actor, Scheduler}
import scala.actors.scheduler.ResizableThreadPoolScheduler

Scheduler.impl = {
val s = new ResizableThreadPoolScheduler(false);
s.start()
s
}

for( x <- 1 to 300) { new A(x).start() }

while(true) { Thread.sleep(5000) }

(The argument `false` says whether the scheduler should be daemon-style
or not.)
The reason `ResizableThreadPoolScheduler` is not the default is that it
is significantly less efficient than the default fork-join based
scheduler. Also, it can be less robust under heavy load if not tuned
properly.

Cheers,
Philipp

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland