Cost of synchronization

2019-02-16 14:13发布

问题:

In a highly concurrent Java program and assuming that my methods are correctly written and correctly synchronized, I am wondering about how to determine which is better:

void synchronized something() {
     ...
}

or

void something() {
     synchronized(this) {
         ...
     }
     // here do stuff no requiring synchronization
     .
     . // do computation 'A'
     .
     synchronized(this) {
         ...
     }
     // here do other stuff no requiring synchronization
     .
     . // do computation 'B'
     .
     synchronized(this) {
         ...
     }
}

Now I realize that if computation 'A' and 'B' takes a lot of time, the second version is obviously better.

My question, however, is : at which point do you know that the second version is more efficient?

Is the second version always faster or is there an hidden cost about acquiring/releasing the lock several times?

What if my computation 'A' is simply something trivial like:

s.getString().substring( 0, 2 ).toLowerCase();

回答1:

Yes, synchronized costs time. If the actual computations are simple and it's inside a loop or so, it costs lots of time compared to the actual computations.

See this example: http://ideone.com/zgpB7

  • Inner part synchronized: approximately 0.025s
  • Whole loop synchronized: less than 0.001s

To determine which one is better for your program, let it perform stuff and look at which time it's faster.



回答2:

thejh makes a good point that there is some cost to repeatedly locking a thread. However, whenever I have talked with people about parallel threads, it has always been about making sure that all the threads execute quickly when running at the same time.

Keeping a lock for longer than required, can slow down the other threads. They have to sit and wait while you are doing work that will not interfere with the work they want to do. If this is a situation where milliseconds actually matter to you, you should use a profiler to see what works best given your situation. Multi-threading optimization is one of those situations where there are "best practices" that generally hold true, but you are not going to get rule that works in all situations. If you need that much granularity, you should test it and see.



回答3:

Does "correctly written" and "correctly synchronized" mean that there are no dependencies between the code-sections in the multi-synchronized case? If there are dependencies, then it could be that the multi-synchronized case could result in violation of an invariant. Put another way, can you guarantee that execution of the multi-synchronized case won't result in some object being in an invalid state? If not, then the single-synchronized case might be better.