Dead End in scala

I want to rewrite in scala an example from Sun's tutorial on concurrency in java. Source code here: http://java.sun.com/docs/books/tutorial/essential/concurrency/deadlock.html

This code is invalid. It freezes where the comment indicates. Can anyone fix this? Thanks in advance.

import scala.actors.Actor class Person(val name: String) extends Actor { def bow(other: Person) { other ! Bow(this) } private def bowBack(backTo: Person) { println(this.name + " is bowing back to " + backTo.name) backTo ! Bowed(this) } def act() { while (true) { receive { case Bow(p) => println(this.name + " is bowing to " + p.name) p ! BowBack(this) println(" wating for bowing back...") var received = false while (true && received == false) { receive { //blocked here case Bowed(other) if p == other => println(" ... " + this.name + " has bowed to " + other.name) received == true } } println(this.name + " has bowed to " + p.name) case BowBack(p) => println(this.name + " is bowing back to " + p.name) p ! Bowed(this) case "EXIT" => return case x => println(x) } } } } abstract case class Action() case class Bow(person: Person) extends Action case class BowBack(person: Person) extends Action case class Bowed(person: Person) extends Action object BowTest extends Application { val a = new Person("Alphone") val g = new Person("Gaston") a.start() g.start() a ! Bow(g) //g.bow(a) a ! "EXIT" g ! "EXIT" } 
+4
source share
2 answers

The first mistake is that you wrote result == true . This should be changed to result = true

You must remove the true value from the while condition. It does not affect.

In BowTest an object that you must add after g.bow(a) Thread.sleep(1000) to give players enough time to reply to messages.

So your code should work. But still he was at an impasse. If you change g.bow(a) to a.bow(g) , execution will freeze. This is caused by the receive block. Each actor is waiting for a Bowed message, but they cannot respond to a BowBack message.

When you reply to a message, you should use the receive block only if you are sure that the actor will receive the specified messages. But usually this is not a good practice in developing actors. They should not be blocked. The main goal of the actor is to respond to the message as quickly as possible. If you need to complete a large task, you should use futures , but in this case it is not required.

The solution is to keep individuals bent on the list. When an actor has to bow to a person, he adds it to the list. When an actor bends over a person on a list, he removes that person from the list.

 while (true) { react { case Bow(p) => println(this.name + " is bowing to " + p.name) addPersonToBowList(p) p ! BowBack(this) case Bowed(other) if isPersonInBowList(other) => println(" ... " + this.name + " has bowed to " + other.name) removePersonFromBowList(other) case BowBack(p) => println(this.name + " is bowing back to " + p.name) p ! Bowed(this) case "EXIT" => exit() case x => println(x) } }
while (true) { react { case Bow(p) => println(this.name + " is bowing to " + p.name) addPersonToBowList(p) p ! BowBack(this) case Bowed(other) if isPersonInBowList(other) => println(" ... " + this.name + " has bowed to " + other.name) removePersonFromBowList(other) case BowBack(p) => println(this.name + " is bowing back to " + p.name) p ! Bowed(this) case "EXIT" => exit() case x => println(x) } } 
+5
source

Not a dead end, just a blunder. Two lines under your comment:

received == true

It should be = instead of == . I did not look in depth (this arose from me), but it looks like this will fix your problem.

0
source

Source: https://habr.com/ru/post/1303103/


All Articles