【发布时间】:2014-06-19 10:30:26
【问题描述】:
嗯,我发现这个问题回答了好几次。答案也很常见。 静态同步方法锁定类,同步方法锁定实例本身。
并且同一类的两个不同线程不能同时调用两个不同的同步方法。如果呼叫则一个被阻止。 静态同步方法也会发生同样的事情。所以在我看来,这两种情况都显示出相同的可用性。如果有人在这两种方法的可用性情况下标记出这两种方法的差异,那将非常有帮助。
【问题讨论】:
标签: java multithreading static synchronized
嗯,我发现这个问题回答了好几次。答案也很常见。 静态同步方法锁定类,同步方法锁定实例本身。
并且同一类的两个不同线程不能同时调用两个不同的同步方法。如果呼叫则一个被阻止。 静态同步方法也会发生同样的事情。所以在我看来,这两种情况都显示出相同的可用性。如果有人在这两种方法的可用性情况下标记出这两种方法的差异,那将非常有帮助。
【问题讨论】:
标签: java multithreading static synchronized
同一类的两个不同线程不能同时调用两个不同的同步方法。
这是一个非常普遍的误解,但并非总是如此。这是总是正确的:没有两个线程可以同时在同一个对象上synchronized。
当在实例方法上使用synchronized 关键字时,该方法的整个主体在this 上同步。假设我们有一个类:
class Foo {
synchronized void doSomething() { ... }
synchronized void doSomethingElse() { ... }
}
这实际上是一种简写方式:
class Foo {
void doSomething() { synchronized (this) { ... }}
void doSomethingElse() { synchronized (this) { ... }}
}
现在假设我们有两个类的实例:
final Foo f1 = new Foo(...);
final Foo f2 = new Foo(...);
线程 B 在 f1.doSomethingElse() 中时线程 A 无法进入 f1.doSomething(),但线程 A 可以在线程 B 在 f2.doSomethingElse() 中。那是因为 f1 和 f2 是 不同的 对象。 synchronized 关键字仅防止两个或多个线程在 same 对象上同步。
static 方法的情况略有不同。本声明:
class Bar {
static synchronized void doSomething() { ... }
static synchronized void doSomethingElse() { ... }
}
与此声明相同:
class Bar {
static void doSomething() { synchronized(Bar.class) { ... }}
static void doSomethingElse() { synchronized(Bar.class) { ... }}
}
static 方法无法在 this 上同步,因为没有为静态方法定义 this。而是在类对象上同步静态方法。
在这种情况下,永远不可能有一个线程在 Bar.doSomething() 中,而另一个线程在 Bar.doSomethingElse() 中运行,因为这两种方法在相同 对象(Bar.class 对象。)
【讨论】:
在下面的代码中
b方法。 t1.a()方法。一个线程调用t1.a() 将不会干扰另一个线程调用t2.a()。
public class Test {
synchronized void a() {
}
static synchronized void b() {
}
public static void main(String args[]) {
final Test t1 = new Test();
final Test t2 = new Test();
// Some threads that just mess with the test objects.
Thread test1 = new Thread() {
public void run() {
while (true) {
t1.a();
}
}
};
Thread test2 = new Thread() {
public void run() {
while (true) {
t2.b();
}
}
};
Thread test3 = new Thread() {
public void run() {
while (true) {
t1.a();
t1.b();
t2.a();
t2.b();
}
}
};
test1.start();
test2.start();
test3.start();
}
}
【讨论】: