I have scoured the internet for an answer to this but unfortunately couldn’t find one. The question is:
Can you have mutable code in an actor’s constructor? For example, if you have this code:
class Example extends Actor {
var counter = 0
counter += 1
override def receive: Receive = {
case any => println(counter)
}
}
Can you rely on the number 1 getting printed every time a message is received? Or in other words, does the constructor code “synchronize” on the same lock that the receive
code does? I guess to answer this one might need internal knowledge of Akka. In any case, any help with this is appreciated.
Short answer: Yes
Long answer: The Java memory model generally guarantees that things done in a constructor is visible to other threads by placing a memory barrier at the end of the constructor, so this is pretty much true of any object that mutates internal state in its constructor that the state in the end of the constructor is visible to all threads. The exception would be if it leaks the incomplete this
to other objects from the constructor.
The additional safety that actors bring to the table is that it is also safe to mutate such fields when processing a message which happens on different threads and that only one message is processed at the same time by the same actor.
Thanks for the reply @johanandren. However, isn’t this special memory barrier treatment applied just for variables marked final
(i.e. scala val
)? A quick google search produced the following reference: https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5 - See example 17.5-1
Yes you are right, that guarantee is only for final fields, the memory fence is only there for final values (in practice, I think, as long as there is at least one final field, as the memory fence is coarse gained - probably not something to rely on though), however for actors there is also memory fencing triggered around message receive to make sure mutable fields are safe to use, so there will be a happens before between construction and processing the first message.
Okay, this is exactly what I was looking for. That’s good to know. Thanks!