1

Is this code ok, or should I create a separate lock object? I am asking if there is a potential for some deadlock or something like that. I assume it should work since the language allows it, but just to be sure I would rather understand how it works and why it is ok or why it is not ok.

var foo = false

fun bar()
{
    synchronized(foo) {
        foo = !foo
    }
}
rozina
  • 4,120
  • 27
  • 49
  • How is it opinion based? The accepted answer is not an opinion and explains why having the same object as your lock could be dangerous. – rozina Nov 20 '17 at 07:37

1 Answers1

3

Your code is broken in a way you might not expect. Here's the simplified version of the bytecode it generates, decompiled to Java:

private static boolean foo;

public static final void bar() {
    Boolean var0 = Boolean.valueOf(foo);
    synchronized(var0) {
        foo = !foo;
    }
}

So you're essentially locking on whatever object the valueOf function returns, which in my JRE is either the TRUE or FALSE singletons inside the Boolean class (this is also simplified):

public class Boolean {
    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);

    public static Boolean valueOf(boolean var0) {
        return var0 ? TRUE : FALSE;
    }
}

Your best bet for certain, runtime independent code is probably to create a separate instance of Any to synchronize on.

zsmb13
  • 85,752
  • 11
  • 221
  • 226
  • This is exactly the information I was looking for. With all the indirection things can get hidden quickly and synchronization bugs are usually hard to debug. Thanks for the info! – rozina Nov 16 '17 at 12:49
  • This happens because my lock is a primitive type? Had it been a non-primitive type this kind of locking would be OK? – rozina Nov 16 '17 at 12:52
  • 1
    It would solve this specific issue that comes from boxing, yes. However, if you'd be reassigning it inside the synchronized block, then the same considerations apply as when you're [synchronizing on a non-final field in Java](https://stackoverflow.com/a/6910838/4465208). I'd still go with a separate sync object. – zsmb13 Nov 16 '17 at 12:57