Synchronizing on an object in java, then changing the value of the synchronized-on variable

后端 未结 4 557
误落风尘
误落风尘 2020-12-11 00:41

I came across a code like this

synchronized(obj) {

   obj = new Object();

}

Something does not feel right about this , I am unable to ex

4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-11 01:11

    If obj is a local variable and no other thread is evaluating it in order to acquire a lock on it as shown here then it doesn't matter. Otherwise this is badly broken and the following applies:

    (Posting this because the other answers are not strongly-worded enough --"probably" is not sufficient here -- and do not have enough detail.)

    Every time a thread encounters a synchronized block, before it can acquire the lock, it has to figure out what object it needs to lock on, by evaluating the expression in parens following the synchronized keyword.

    If the reference is updated after the thread evaluates this expression, the thread has no way of knowing that. It will proceed to acquire the lock on the old object that it identified as the lock before. Eventually it enters the synchronized block locking on the old object, while another thread (that tries to enter the block after the lock changed) now evaluates the lock as being the new object and enters the same block of the same object holding the new lock, and you have no mutual exclusion.

    The relevant section in the JLS is 14.19. The thread executing the synchronized statement:

    1) evaluates the expression, then

    2) acquires the lock on the value that the expression evaluates to, then

    3) executes the block.

    It doesn't revisit the evaluation step again at the time it successfully acquires the lock.

    This code is broken. Don't do this. Lock on things that don't change.

提交回复
热议问题