是对象级别的。也就是说:一个线程拿到某个对象的锁(通过调用syschronized方法或者进入syschronized代码块),那么在它释放该锁之前,该对象的其他syschronized方法和syschronized代码块都是不允许其他线程进入的。下面的例子演示了这一点:public class Test {
public static void main(String[] args){
final Test test1 = new Test(); final Test test2 = new Test(); new Thread() { public void run() { test1.f(); } }.start();
new Thread() { public void run() { test1.g(); } }.start();
new Thread() { public void run() { test1.h(); } }.start();
new Thread() { public void run() { test2.g(); } }.start();
public static void main(String[] args){
final Test test1 = new Test();
final Test test2 = new Test();
new Thread() {
public void run() {
test1.f();
}
}.start();
new Thread() {
public void run() {
test1.g();
}
}.start();
new Thread() {
public void run() {
test1.h();
}
}.start();
new Thread() {
public void run() {
test2.g();
}
}.start();
}
synchronized void f() {
System.out.println(this+".f()");
try {
Thread.sleep(5000);
} catch(Exception e) {
System.out.println("Who wakes me up?");
}
System.out.println("I'm done sleeping.");
}
synchronized void g() {
System.out.println(this+".g()");
}
void h() {
System.out.println(this+".h()");
}
}f()是同步的,它一旦被调用,调用它的线程就持有对象的锁5秒钟。
所以,第一个线程开始后,test1的锁被持有,第二个线程虽然不是调用test1的f()方法,但由于g()也是同步的,所以它因为拿不到test1的锁而被挂起。
第三个线程调用的是非同步方法,第四个线程调用的是另一个对象test2的同步方法,因此它们都不需要等待就可以执行。