Java: Is volatile / final required for reference to synchronized object?

后端 未结 5 800
陌清茗
陌清茗 2021-01-04 02:52

This seems a pretty basic issue, but I cannot find a clear confirmation.

Let\'s say I have a class properly synchronized in itself:

public class Sync         


        
5条回答
  •  失恋的感觉
    2021-01-04 03:35

    It's not mandatory to use any of them but you should know about them if you want to write proper multi-threaded code.

    Final

    final means you cannot re-initialize that variable again, so when you say

    final SyncClass mySharedObject = new SyncClass();
    

    you cannot do the initialization of mySharedObject again in some other part of code like below

       mySharedObject = new SyncClass(); // throws compiler error
    

    Even though you cannot re-assign mySharedObject reference to some other object, you can still update it's state (field counter variable) by calling methods on it because field is not final.

    Synchronization and volatile are just constructs to ensure that any change to a shared mutable object (in this case updating a field counter) by one thread is visible to all other threads.

    Synchronization

    synchronized method means that any thread trying to invoke that method should acquire a lock on the object in which that method is defined.

    So in your case, If thread-1 is trying to do mySharedObject.doSomething(), it will acquire lock on mySharedObject and thread-2 has to wait until thread-1 releases that lock on the same object to be able to do mySharedObject.doSomethingElse() i.e using Synchronization at any given point of time, only ONE thread will update the state of the object. At the end of the method, just before releasing the lock all the changes done by thread-1 are flushed to main memory so that thread-2 can work on the recent state.

    Volatile

    volatile on the other hand ensures read/write visibility to all the threads. Any read and write to volatile variable are always flushed to main memory.

    If your field variable inside SyncClass is volatile, any update like field++ by thread-1 is visible to thread-2 but I'm not sure how it applies to object references.

    As volatile only guarantees visibility but not atomicity, it's possible that both thread-1 and thread-2 try to update field counter at the same time and the final updated value may not be proper.

提交回复
热议问题