Every time I read about using synchronized
in Scala the author will usually mention that Actors should be used instead (this for example). While I understand roughl
Actors guarantee that only a single message will be handles at time so that there will not be two threads accessing any of the instance members - ergo no need to use synchronized
1) Overview
Scala Actors can replace the complex business logic in a standard Java threaded application s which often evade developers working on complex multithreaded systems.
Consider the following java code snippet that one might see in a a simple, threaded application (this code is waiting for an asynchronous request to complete).
myAsyncRequest.startCalculation();
while(notDone)
myAsyncRequest.checkIfDone();
Thread.sleep(1000);
System.out.println("Done ! Value is : " + myAsyncRequest.getCalculationValue());
To see a direct replacement of this sort of code using Scala's higher level concurrency model, check this post out : Scala program exiting before the execution and completion of all Scala Actor messages being sent. How to stop this?
2) Now : back to the code snpipet --- There are some obvious issues here, lets take a quick look :
How does scala modify this paradigm ?
These encapsulate the expectation that, soon enough, the "thing" that you want an actor to do will be accomplished. The scala "future" replaces this java construct : It makes "explicit" the fact that , my while loop is "expecting" something to occur in the near future, and there is an action to be done afterwards.
Although I'm "waiting" (in the while loop above) for completion, its obvious that another way to implement would be if the calculation object would simply "tell me" when it was done. Message passing enables this, but is somewhat complicated and leads to untraceable, unreadable code in some java implementations. Since scala abstracts this notion in such a way that is directly designed to accomodate concurrent work-loads, the message passing design pattern can now be implemented in a way which isn't overly complex, thus decoupling the logic of "waiting" from the logic of processing.
3) The short answer : In general, the scala API's are built to encode concurrent logic at a higher level of abstraction, so that you're concurrent code is declarative, rather than muddled in implementation details.
4) Synchronization : A lower-level concept which , although essential, can complicate our code .
Synchronization is an artifact of lower-level, multithreaded programming. By providing higher level abstractions of the most common parallel programming paradigms, Scala makes this particular construct unnecessary in many of the most common concurrent programming user cases. In fact, nowadays, even java does this :) The java.util.concurrent package gives us atomic data types and data structures, obviating the need to wrap simple operations in "synchronized" blocks. However, standard Java does not support the higher level notions of "Actors" and "Futures" which can be effectively managed and coordinated without needing to manually manage synchronized method calls or object modifications.