Hacker News new | ask | show | jobs
by glic3rinu 3024 days ago
With the actor model you don't share state between threads, hence no need to lock anything.

Each variable can only be updated by a single and unique thread. If another thread (or actor) wants to modify it, it has to send a modification request messages to that one thread to do the job.

That's quite a difference!

Edit: Java threading model is fine for limited amounts of concurrency. Complexity escalates quickly with highly concurrent applications; the actor model makes reasoning about those programs far easier.

1 comments

So it's like a lock, except you call it "modification request". Great, got it.
The difference is that it doesn't halt your execution unless you want it to. With shared memory and locks you have to wait when you set a value if anyone else is interacting with that object or that part of the object (if you have fine-grained locks). So you wait both for getting and setting.

If your system behavior does not immediately depend on the value of what you're changing, then actors are fantastic. You don't wait, it's async. You send the data to the controlling actor (which is an object in the OO sense itself). Your process continues on as if nothing changed until you need the updated results.

  Process A
    B ! {update, x, newVal},
    %% A bunch of work
    B ! {lookup, y, A}, % where y perhaps depended on x
    Y = receive % Here we finally wait, if B is processing a lot of requests
      {B,y,Val} -> Val
    end,
    %% more work

  Process B
  loop(State) ->
    receive
      {update, Var, Val} -> loop(update(State,Var,Val));
      {lookup, Var, Pid} -> Pid ! lookup(State, Var), loop(State)
    end.
Where B may be much more complex than that, in this case it looks like a simple KV store.

The receive at the end of Process A is blocking and is the only time we end up with a lock in Process A. So if A never needs to do anything but send values to B, then A can run undisturbed by everyone else's data requests. This lends itself well to certain pipelined and dataflow architectures.

Similar in the sense that they protect data from being accessed by multiple threads at once. But the implementation and semantics are quite different.

The main practical drawback, I would say, is that locks may suffer from the mutual exclusion problem; where you have contention, starvation and deadlocking. Also your ability to parallelize operations over shared state quickly vanishes as the number of threads grow...