好吧,我发现这个问题已经回答了几次。答案也很常见。 静态同步方法锁定 Class ,其中synchronized方法锁定实例本身。
同一类的两个不同的线程不能同时调用两个不同的同步方法。如果呼叫则阻止一个。 静态同步方法也会发生同样的事情。因此在我看来,两种情况都表现出相同的可用性。如果有人在这两种方法的可用性方面有所区别,那将会非常有帮助。
答案 0 :(得分:1)
同一类的两个不同的线程不能同时调用两个不同的同步方法。
这是一种非常常见的误解,但并非总是如此。这里的总是是什么:同一个对象上没有两个线程可以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输入f1.doSomething()时 是可能的线程B在f2.doSomethingElse()中。这是因为f1和f2是不同的对象。 synchronized
关键字仅阻止两个或多个线程在相同的对象上进行同步。
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()中运行,因为两个方法在同步< / em> object(Bar.class对象。)
答案 1 :(得分:0)
在下面的代码中
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();
}
}