问题
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 roughly how actors work I'd really like to see an example of Actors being used to replace Java's synchronized
method modifier (by this I mean its Scala equivalent - the synchronized
block) in a piece of code. Modifying the internals of a data structure for instance would be nice to see.
Is this a good use of Actors or have I been misinformed?
回答1:
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
回答2:
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 :
- The code is coupling the logic of "monitoring" the execution of calculation to the processing of the calculated results.
- There are heuristics embedded in the code (Thread.sleep(1000)) which have no clear logical justification (why wait a second ? Why not wait 3 seconds ?), thus adding unecessary logic to the code block.
- It doesnt scale - if I'm running 1000 clients, and each is constantly checking the results, I could generate some pretty ugly traffic --- for no good reason.
How does scala modify this paradigm ?
- Scala actors can return "futures"
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.
- Scala actors can pass "messages"
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.
来源:https://stackoverflow.com/questions/8215878/using-actors-instead-of-synchronized