-6

This honestly compiles and runs in Java 7

Just what the question says - while it is technically legal to do so, if you call synchronized on some method variable, does it actually achieve anything? Or is it, because method variables exist within their own little world, going to fail to achieve anything worthwhile?

eg:

public int getX(){
    Integer k = 12;
    synchronized (k) {
        System.out.println("meow");
    }
    return x;
}
bharal
  • 15,461
  • 36
  • 117
  • 195
  • "_while it is technically legal to do so_". Nope; it is not. See the [JLS](https://docs.oracle.com/javase/specs/jls/se8/html/index.html). – Boris the Spider Dec 23 '16 at 18:55
  • What do yuo mean by "method variable" a local object created inside method or an object passed as parameter to the method? – shanmuga Dec 23 '16 at 18:59
  • @BoristheSpider i don't know about you, but I can literally write code that does it - as in the edited question - that does that and it compiles and runs fine. I'm using Java 7 on my machine right now though (because of requirements from other software I use). – bharal Dec 23 '16 at 18:59
  • @bharal that's not "_call[ing] synchronized on some method variable_", it's a [`synchronized` statement](https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.19). It does what the JLS says it does - provides synchronized access to the block with the variable instance in question as the lock. – Boris the Spider Dec 23 '16 at 19:00
  • @BoristheSpider sure, whatever. You're not answering the question though - maybe my question is insane, or you don't understand the question? Also referring to *the entire JLS* isn't a very useful thing to do, regarding your first comment! – bharal Dec 23 '16 at 19:03
  • @bharal I linked to the [specific section](https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.19) in [my comment](https://stackoverflow.com/questions/41306513/can-you-call-synchronized-on-a-method-variable?noredirect=1#comment69816176_41306513) when you clarified your question. – Boris the Spider Dec 23 '16 at 19:05
  • @BoristheSpider Oh! I didn't hit that last link. And it still doesn't answer my question. And your first comment is still wrong because it is technically legal. – bharal Dec 23 '16 at 19:06

1 Answers1

2

You're asking the wrong question. Whether the variable is local is irrelevant, as shown in the following example:

class Test {
    private Map<String, String> map = new HashMap<>();

    public void put(String key, String value) {
        Map<String, String> localMap = this.map;
        synchronized (localMap) {
            localMap.put(key, value);
        }
    }
}

The local reference is actually necessary if there's a possibility that the field could be replaced while you're in the synchronized block.

So the real question is whether you should ever lock on a private value, that is, an object not available to other threads. You may think your example demonstrates such a case, but per the JLS, the autoboxed Integer 12 is cached, meaning you're actually synchronizing on a global value.

Now, assuming you have a local value that's actually private to its thread, there's generally no point in synchronizing on it, and I think some analyzers will warn you if you try. However, see here and here for a possible exception.

Community
  • 1
  • 1
shmosel
  • 49,289
  • 6
  • 73
  • 138