Why is synchronized block better than synchronized method?

后端 未结 10 961
Happy的楠姐
Happy的楠姐 2020-12-07 08:05

I have started learning synchronization in threading.

Synchronized method:

public class Counter {

   private static int count = 0;

   public stati         


        
相关标签:
10条回答
  • 2020-12-07 08:25

    It should not be considered as a question of best for usage, but it really depends on the use case or the scenario.

    Synchronized Methods

    An entire method can be marked as synchronized resulting an implicit lock on the this reference (instance methods) or class (static methods). This is very convenient mechanism to achieve synchronization.

    Steps A thread access the synchronized method. It implicitly acquires the lock and execute the code. If other thread want to access the above method, it has to wait. The thread can't get the lock, will be blocked and has to wait till the lock is released.

    Synchronized Blocks

    To acquire a lock on an object for a specific set of code block, synchronized blocks are the best fit. As a block is sufficient, using a synchronized method will be a waste.

    More specifically with Synchronized Block , it is possible to define the object reference on which are want to acquire a lock.

    0 讨论(0)
  • 2020-12-07 08:27

    The difference is in which lock is being acquired:

    • synchronized method acquires a lock on the whole object. This means no other thread can use any synchronized method in the whole object while the method is being run by one thread.

    • synchronized blocks acquires a lock in the object between parentheses after the synchronized keyword. Meaning no other thread can acquire a lock on the locked object until the synchronized block exits.

    So if you want to lock the whole object, use a synchronized method. If you want to keep other parts of the object accessible to other threads, use synchronized block.

    If you choose the locked object carefully, synchronized blocks will lead to less contention, because the whole object/class is not blocked.

    This applies similarly to static methods: a synchronized static method will acquire a lock in the whole class object, while a synchronized block inside a static method will acquire a lock in the object between parentheses.

    0 讨论(0)
  • 2020-12-07 08:31

    In your case both are equivalent!

    Synchronizing a static method is equivalent to a synchronized block on corresponding Class object.

    In fact when you declare a synchronized static method lock is obtained on the monitor corresponding to the Class object.

    public static synchronized int getCount() {
        // ...
    }
    

    is same as

    public int getCount() {
        synchronized (ClassName.class) {
            // ...
        }
    }
    
    0 讨论(0)
  • 2020-12-07 08:32

    Define 'better'. A synchronized block is only better because it allows you to:

    1. Synchronize on a different object
    2. Limit the scope of synchronization

    Now your specific example is an example of the double-checked locking pattern which is suspect (in older Java versions it was broken, and it is easy to do it wrong).

    If your initialization is cheap, it might be better to initialize immediately with a final field, and not on the first request, it would also remove the need for synchronization.

    0 讨论(0)
  • 2020-12-07 08:33

    It's not a matter of better, just different.

    When you synchronize a method, you are effectively synchronizing to the object itself. In the case of a static method, you're synchronizing to the class of the object. So the following two pieces of code execute the same way:

    public synchronized int getCount() {
        // ...
    }
    

    This is just like you wrote this.

    public int getCount() {
        synchronized (this) {
            // ...
        }
    }
    

    If you want to control synchronization to a specific object, or you only want part of a method to be synchronized to the object, then specify a synchronized block. If you use the synchronized keyword on the method declaration, it will synchronize the whole method to the object or class.

    0 讨论(0)
  • 2020-12-07 08:33

    Although not usually a concern, from a security perspective, it is better to use synchronized on a private object, rather than putting it on a method.

    Putting it on the method means you are using the lock of the object itself to provide thread safety. With this kind of mechanism, it is possible for a malicious user of your code to also obtain the lock on your object, and hold it forever, effectively blocking other threads. A non-malicious user can effectively do the same thing inadvertently.

    If you use the lock of a private data member, you can prevent this, since it is impossible for a malicious user to obtain the lock on your private object.

    private final Object lockObject = new Object();
    
    public void getCount() {
        synchronized( lockObject ) {
            ...
        }
    }
    

    This technique is mentioned in Bloch's Effective Java (2nd Ed), Item #70

    0 讨论(0)
提交回复
热议问题