-11

What is the difference between the following approaches of placing a lock with concurrency?

public synchronized ArrayList<Player> getPlayers() {
     return players;
}

public ArrayList<Player> getPlayers() {
     synchronized(players) {
          return players;
     }
}

public ArrayList<Player> getPlayers() {
     synchronized(GameHandler.class) {
          return players;
     }
}

How do we decide which one should be used in which scenarios?

Edit:

I have edited my thread title and post to prove this is not a duplicate. Thank you.

  • no difference, all three will only allow a single thread to access `players` in these methods at any one time. – Scary Wombat Aug 07 '14 at 04:55
  • What is the point of having three ways to do it? – 0-4930-42390eo23o2e0-23oe0-23o Aug 07 '14 at 04:55
  • You may get your answer here: http://stackoverflow.com/questions/20906548/why-is-synchronized-block-better-than-synchronized-method – Mandar Pandit Aug 07 '14 at 04:56
  • OK, the result in these methods is the same. – Scary Wombat Aug 07 '14 at 04:57
  • That doesn't answer my question. – 0-4930-42390eo23o2e0-23oe0-23o Aug 07 '14 at 04:57
  • First and second case are almost same when consider the functionality. If one Thread already acquire the lock other method will wait to get the lock. But third case is little deferent. If one Thread already acquire the lock using shared object `GameHandler.class` that thread can acquire new lock. But other Thread have to wait – Ruchira Gayan Ranaweera Aug 07 '14 at 04:57
  • @RuchiraGayanRanaweera unless one is using recursion, then how can one Thread acquire a new lock? – Scary Wombat Aug 07 '14 at 04:59
  • 6
    If you don't think this is a duplicate then please edit it to make it clear where it's different. It will then go on the reopen review queue. – ChrisF Aug 07 '14 at 07:34
  • the first two synchronize on the instance object, the last one on the class (which is equivalent to a `synchronized static` method). With a synchronized block instead of method you can be more selective. It is typically good to have smaller blocks. However when you need to lock the whole method some JVMs are a bit faster when the whole method is marked synchronized (less byte code). – eckes Aug 10 '14 at 04:15

1 Answers1

7

Before I answer you question, note that a void method can't return an ArrayList.

And to the question: They differ in the lock they acquire.

In this case, the first one is an implicit lock on "this". It's a way to write

public void getPlayers() {
    synchronized (this) {
        return list;
    }
}

Except that it is a method modifier.

In the second example, you explicitly lock on the ArrayList you are returning. This is common with contended locks, switching the instance lock with a more localized grain.

In the third example, you lock on the Class. This is usually the preferred choice of static methods, where the instance cannot be acquired (try it, you can't use "this" as a value). It's pretty much equivalent to locking on a static final Object field, since the Class object theoretically shouldn't change.

  • I know a void can't return an ArrayList. That's why I edited it. Thanks for your answer. – 0-4930-42390eo23o2e0-23oe0-23o Aug 07 '14 at 05:01
  • It happens to a lot of people new to a specific area of Java. I try to help people I can, but ultimately, it's up to you to do the research on concurrency as well. I have personally read Java Concurrency In Practice, and is a must-have for any Java developer, as multi threading will get more and more important as CPU power get underutilized by single threaded applications. –  Aug 07 '14 at 05:03
  • Good answer, good attitude, and good humor (being ignorant!)... so have a plussie! You're not a very good troll, are you? ;) – Andrew Barber Aug 07 '14 at 16:44
  • 3
    My job as a troll is not to troll, and that's the troll :P –  Aug 07 '14 at 16:57