Avoid synchronized(this) in Java?

后端 未结 22 1186
予麋鹿
予麋鹿 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 01:55

    The reason not to synchronize on this is that sometimes you need more than one lock (the second lock often gets removed after some additional thinking, but you still need it in the intermediate state). If you lock on this, you always have to remember which one of the two locks is this; if you lock on a private Object, the variable name tells you that.

    From the reader's viewpoint, if you see locking on this, you always have to answer the two questions:

    1. what kind of access is protected by this?
    2. is one lock really enough, didn't someone introduce a bug?

    An example:

    class BadObject {
        private Something mStuff;
        synchronized setStuff(Something stuff) {
            mStuff = stuff;
        }
        synchronized getStuff(Something stuff) {
            return mStuff;
        }
        private MyListener myListener = new MyListener() {
            public void onMyEvent(...) {
                setStuff(...);
            }
        }
        synchronized void longOperation(MyListener l) {
            ...
            l.onMyEvent(...);
            ...
        }
    }
    

    If two threads begin longOperation() on two different instances of BadObject, they acquire their locks; when it's time to invoke l.onMyEvent(...), we have a deadlock because neither of the threads may acquire the other object's lock.

    In this example we may eliminate the deadlock by using two locks, one for short operations and one for long ones.

提交回复
热议问题