如果你锁定了一个对象,你是否锁定了它的所有方法?
If you have a lock on an object, do you have a lock on all its methods?
假设我们有一个对象 foo:
class Foo(){
public synchronized void instanceMethod(){}
}
var foo = new Foo();
如果我锁定了 foo:
synchronized(foo){
foo.instanceMethod();
}
我是否也锁定了 instanceMethod()
调用?另一种提问方式——如果我锁定了 foo,另一个线程可以调用 foo.instanceMethod()(同时)吗?
if I have a lock on foo, can another thread call foo.instanceMethod()?
他们可以调用它,但调用将等到执行离开您的块 synchronized
在 foo
,因为 instanceMethod
是 synchronized
。声明一个实例方法 synchronized
与将其整个主体放在 this
.
上的块 synchronized
中大致相同
如果instanceMethod
没有同步,那么调用当然不会等待。
不过请注意,您显示的 synchronized
块是不必要的:
synchronized(foo){ // <==== Unnecessary
foo.instanceMethod();
}
因为instanceMethod
是synchronized
,所以可以是:
foo.instanceMethod();
...除非块中还有其他东西。
class Foo {
public synchronized void a() { //Do something }
public void b() {
synchronized(this) { // Do something }
}
public void c() { // Do something }
}
然后:
Foo foo = new Foo();
foo.a();
foo.b();
synchronized(foo) { foo.c(); }
这 3 种方法在同步方面都非常相似。
没有“锁定”方法这样的东西。锁定仅在对象上完成。标记方法 synchronized
只是使其锁定实例(或其静态方法的 class 对象)。
当您访问锁定对象上的方法时,执行将被阻止,因为线程无法检索指定对象的 monitor - 甚至在方法执行之前被称为。因此 foo.a()
在获取 foo
.
时将被阻止
添加...
突然想起一件事。如果你有线程 A 调用 foo.a()
并且它需要很长时间才能完成,而此时另一个线程调用 foo.c()
,那么 foo.c()
仍然会被阻塞直到 foo.a()
完成。
假设我们有一个对象 foo:
class Foo(){
public synchronized void instanceMethod(){}
}
var foo = new Foo();
如果我锁定了 foo:
synchronized(foo){
foo.instanceMethod();
}
我是否也锁定了 instanceMethod()
调用?另一种提问方式——如果我锁定了 foo,另一个线程可以调用 foo.instanceMethod()(同时)吗?
if I have a lock on foo, can another thread call foo.instanceMethod()?
他们可以调用它,但调用将等到执行离开您的块 synchronized
在 foo
,因为 instanceMethod
是 synchronized
。声明一个实例方法 synchronized
与将其整个主体放在 this
.
synchronized
中大致相同
如果instanceMethod
没有同步,那么调用当然不会等待。
不过请注意,您显示的 synchronized
块是不必要的:
synchronized(foo){ // <==== Unnecessary
foo.instanceMethod();
}
因为instanceMethod
是synchronized
,所以可以是:
foo.instanceMethod();
...除非块中还有其他东西。
class Foo {
public synchronized void a() { //Do something }
public void b() {
synchronized(this) { // Do something }
}
public void c() { // Do something }
}
然后:
Foo foo = new Foo();
foo.a();
foo.b();
synchronized(foo) { foo.c(); }
这 3 种方法在同步方面都非常相似。
没有“锁定”方法这样的东西。锁定仅在对象上完成。标记方法 synchronized
只是使其锁定实例(或其静态方法的 class 对象)。
当您访问锁定对象上的方法时,执行将被阻止,因为线程无法检索指定对象的 monitor - 甚至在方法执行之前被称为。因此 foo.a()
在获取 foo
.
添加...
突然想起一件事。如果你有线程 A 调用 foo.a()
并且它需要很长时间才能完成,而此时另一个线程调用 foo.c()
,那么 foo.c()
仍然会被阻塞直到 foo.a()
完成。