If you have a lock on an object, do you have a lock on all its methods?

社会主义新天地 提交于 2019-12-13 14:23:54

问题


Say we have a object foo:

class Foo(){
  public synchronized void instanceMethod(){}
}

var foo = new Foo();

if I have a lock on foo:

synchronized(foo){
  foo.instanceMethod();
}

do I also have a lock on the instanceMethod() call? Another way of asking the question - if I have a lock on foo, can another thread call foo.instanceMethod() (simultaneously)?


回答1:


if I have a lock on foo, can another thread call foo.instanceMethod()?

They can call it, but the call will wait until execution leaves your block synchronized on foo, because instanceMethod is synchronized. Declaring an instance method synchronized is roughly the same as putting its entire body in a block synchronized on this.

If instanceMethod weren't synchronized, then of course the call wouldn't wait.

Note, though, that the synchronized block you've shown is unnecessary:

synchronized(foo){       // <==== Unnecessary
  foo.instanceMethod();
}

Because instanceMethod is synchronized, that can just be:

foo.instanceMethod();

...unless there's something else in the block as well.




回答2:


class Foo {
    public synchronized void a() { //Do something }
    public void b() {
        synchronized(this) { // Do something }
    }
    public void c() { // Do something }
}

Then:

Foo foo = new Foo();
foo.a();
foo.b();
synchronized(foo) { foo.c(); }

All the 3 methods are all pretty much equivalent in terms of synchronization.

There is no such thing as "locking" a method. Locking is done only on objects. Marking a method synchronized simply makes it lock the instance (or its class object for static method).

When you access a method on a locked object, the execution would be blocked as the thread fails to retrieve the monitor for the specified object - that is even before the method has been called. So foo.a() would be blocked when it is getting the foo.

Adding on...

I suddenly remembered something. If you have thread A calling foo.a() and it is taking a very long time to complete, and at that time another thread calls foo.c(), then foo.c() will still be blocked until foo.a() completes.



来源:https://stackoverflow.com/questions/54626010/if-you-have-a-lock-on-an-object-do-you-have-a-lock-on-all-its-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!