Avoid synchronized(this) in Java?

后端 未结 22 1410
予麋鹿
予麋鹿 2020-11-22 01:23

Whenever a question pops up on SO about Java synchronization, some people are very eager to point out that synchronized(this) should be avoided. Instead, they c

22条回答
  •  野的像风
    2020-11-22 02:00

    My two cents in 2019 even though this question could have been settled already.

    Locking on 'this' is not bad if you know what you are doing but behind the scene locking on 'this' is (which unfortunately what synchronized keyword in method definition allows).

    If you actually want users of your class to be able to 'steal' your lock (i.e. prevent other threads from dealing with it), you actually want all the synchronized methods to wait while another sync method is running and so on. It should be intentional and well thought off (and hence documented to help your users understand it).

    To further elaborate, in the reverse you must know what you are 'gaining' (or 'losing' out on) if you lock on a non accessible lock (nobody can 'steal' your lock, you are in total control and so on...).

    The problem for me is that synchronized keyword in the method definition signature makes it just too easy for programmers not to think about what to lock on which is a mighty important thing to think about if you don't want to run into problems in a multi-threaded program.

    One can't argue that 'typically' you don't want users of your class to be able to do these stuff or that 'typically' you want...It depends on what functionality you are coding. You can't make a thumb rule as you can't predict all the use cases.

    Consider for e.g. the printwriter which uses an internal lock but then people struggle to use it from multiple threads if they don't want their output to interleave.

    Should your lock be accessible outside of the class or not is your decision as a programmer on the basis of what functionality the class has. It is part of the api. You can't move away for instance from synchronized(this) to synchronized(provateObjet) without risking breaking changes in the code using it.

    Note 1: I know you can achieve whatever synchronized(this) 'achieves' by using a explicit lock object and exposing it but I think it is unnecessary if your behaviour is well documented and you actually know what locking on 'this' means.

    Note 2: I don't concur with the argument that if some code is accidentally stealing your lock its a bug and you have to solve it. This in a way is same argument as saying I can make all my methods public even if they are not meant to be public. If someone is 'accidentally' calling my intended to be private method its a bug. Why enable this accident in the first place!!! If ability to steal your lock is a problem for your class don't allow it. As simple as that.

提交回复
热议问题