[concurrency-interest] Synchronizing on methods than on code blocks is faster

Aleksey Shipilev aleksey.shipilev at oracle.com
Mon Sep 28 10:18:29 EDT 2015

On 09/28/2015 04:40 PM, Ionut wrote:
> Please correct me if I my test is wrong or I a miss something.

I don't understand a few things:

 a) What are the errors for your measurements? You can't say "slightly
better" unless you can statistically infer it (at very least by
assessing the margins of error).

 b) The code fragments in SynchMethod and SynchBlock are not, strictly
speaking, semantically equivalent: SynchBlock does the unsynchronized
counter.x read. This already partially invalidates the evidence without
the analysis whether this semantic difference is nil in practice.

 c) Why this benchmark is asymmetric with @Group. Each group in your
benchmark has a single method, which means the benchmark is actually
symmetric, and the entire @Group business can be dropped.

 d) Why forks(0)? This is unreliable when estimating the run-to-run
variance, and some other tricks to work.

 e) Why explicit CounterStructure? You may as well put the field in the
enclosing class, since it's already @State.

Nevertheless, this benchmark provides the same performance in both test
on my i7-4790K, Linux x86_64, JDK 8u40:

  @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
  @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
  @Fork(value = 3, jvmArgsAppend = "-XX:BiasedLockingStartupDelay=0")
  public class SMvSB {
      int x;

      public synchronized int syncMethod() {
          return x;

      public int syncBlock() {
          synchronized (this) {
          return x;

  Benchmark          Mode  Cnt    Score   Error   Units
  SMvSB.syncBlock   thrpt   15  244.156 ± 1.048  ops/us
  SMvSB.syncMethod  thrpt   15  244.913 ± 0.775  ops/us

...and this is because both tests use biased locks, and both syncBlock
and syncMethod reused the "x++" value without reading it the second time
-- you can clearly see that with "-prof perfasm". (Or, in other
interpretation, one can think as "return x" soaked into synchronized block).

The same thing happens with -XX:-UseBiasedLocking, although with a
significant throughput hit:

  Benchmark          Mode  Cnt   Score   Error   Units
  SMvSB.syncBlock   thrpt   15  57.474 ± 0.494  ops/us
  SMvSB.syncMethod  thrpt   15  57.886 ± 0.107  ops/us

Explaining the throughput hit (not speculating/handwaving about it, but
actually explaining with the profiling evidence: -prof perfasm and -prof
perfnorm are your friends here) is left as an exercise for a reader.
Don't shrug it off, it is actually a good and simple exercise in


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20150928/abe03a76/attachment-0001.bin>

More information about the Concurrency-interest mailing list