Mi simulación utiliza actores y Scala 2.8-Snapshot. En Java JRE 1.5 funciona bien: los 40 engranajes (actores) funcionan simultáneamente. Con Java JRE 1.6, solo 3 engranajes funcionan simultáneamente. Lo probé con y sin GUI: ambos dan el mismo resultado.Scala Actores: comportamiento diferente en JRE 1.5 y 1.6
Mi simulación con interfaz gráfica de usuario está disponible en GitHub: http://github.com/pmeiclx/scala_gear_simulation
Tal vez usted recuerde a my first problem with actors. Después de resolver estos problemas hice una GUI para la simulación y obtuve este nuevo comportamiento "extraño".
Aquí está el código sin interfaz gráfica de usuario:
package ch.clx.actorversions
import actors.Actor
import actors.Actor._
import collection.mutable.ListBuffer
case class ReceivedSpeed(gear: Gear)
case object StartSync
case class SyncGear(controller: GearController, syncSpeed: Int)
object ActorVersion {
def main(args:Array[String]) = {
println("[App] start with creating gears")
val gearList = new ListBuffer[Gear]()
for (i <- 0 until 100) {
gearList += new Gear(i)
}
val gearController = new GearController(gearList)
gearController.start()
gearController ! StartSync
}
}
/**
* CONTROLLER
*/
class GearController(nGears: ListBuffer[Gear]) extends Actor {
private var syncGears = new ListBuffer[Gear]
private var syncSpeed = 0
def act = {
while(true) {
receive {
case StartSync => {
println("[Controller] Send commands for syncing to gears!")
var speeds = new ListBuffer[Int]
nGears.foreach(e => speeds += e.speed)
//Calc avg
//var avgSpeed = speeds.foldLeft(0)(_ + _)/speeds.length
//var avgSpeed = speeds.foldLeft(0) { (x, y) => x + y }/speeds.length
syncSpeed = (0/:speeds)(_ + _)/speeds.length //Average over all gear speeds
//TODO syncSpeed auf Median ausrichten
println("[Controller] calculated syncSpeed: "+syncSpeed)
nGears.foreach{e =>
e.start()
e ! SyncGear(this, syncSpeed)
}
println("[Controller] started all gears")
}
case ReceivedSpeed(gear: Gear) => {
println("[Controller] Syncspeed received by a gear ("+gear.gearId+")")
//println("[Controller] mailboxsize: "+self.mailboxSize)
syncGears += gear
if(syncGears.length == nGears.length) {
println("[Controller] all gears are back in town!")
System.exit(0)
}
}
case _ => println("[Controller] No match :(")
}
}
}
}
/**
* GEAR
*/
class Gear(id: Int) extends Actor {
private var mySpeed = scala.util.Random.nextInt(1000)
private var myController: GearController = null
def speed = mySpeed
def gearId = id
/* Constructor */
println("[Gear ("+id+")] created with speed: "+mySpeed)
def act = {
loop {
react {
case SyncGear(controller: GearController, syncSpeed: Int) => {
//println("[Gear ("+id+")] activated, try to follow controller command (form mySpeed ("+mySpeed+") to syncspeed ("+syncSpeed+")")
myController = controller
adjustSpeedTo(syncSpeed)
}
}
}
}
def adjustSpeedTo(targetSpeed: Int) = {
if(targetSpeed > mySpeed) {
mySpeed += 1
self ! SyncGear(myController, targetSpeed)
}else if(targetSpeed < mySpeed) {
mySpeed -= 1
self ! SyncGear(myController, targetSpeed)
} else if(targetSpeed == mySpeed) {
callController
}
}
def callController = {
println("[Gear ("+id+")] has syncSpeed")
myController ! ReceivedSpeed(this)
}
}
FYI: Le expliqué este problema a Philipp Haller y lo arregló en el maletero. Entonces, cuando se libere 2.8, no debería tener el problema. https://lampsvn.epfl.ch/trac/scala/changeset/20950/scala/trunk/src/actors –
Disculpe, estaba un poco ocupado. Con la nueva instantánea, funciona. No es perfecto, pero funciona. ¡Gracias! – meip