要理解 synchronized 关键字,可以先看看这篇文章:
http://www.learndiary.com/archives/diaries/2910.htm
本文是对该文的补充。
作者在最后对类中的 static 块是否是同步的抱有疑惑。其实想鉴定也不难。通过编译代码我们就知道,synchronized static {} 这样写是不允许的。为什么呢?因为 static 块的执行属于类加载的一部分。类加载这个动作,按道理说应该是同步的。如果是这样的话,static 块就已经同步了,不需要再加 synchronized。
光是猜想还不行,要写程序来验证。写验证程序也是锻炼思维的手段,某些初学者懒就懒在这里。只要你肯下功夫自己动手而不是到处发帖子问,你就能做到比别人强。
// 创建多个线程,它们几乎同时创建 TestClass 对象。
public static void main(String[] args) {
new CreateTestClassThread().start();
new CreateTestClassThread().start();
new CreateTestClassThread().start();
new CreateTestClassThread().start();
}
// 创建 TestClass 对象的线程
static class CreateTestClassThread extends Thread {
@Override
public void run() {
new TestClass();
}
}
}
class TestClass {
public static final Object lock = new Object();
// static 块只会执行一次。当一个线程进入时,其他线程会等待该线程执行完,然后跳过。
static {
try {
System.out.printf("Thread %d enters static block./n",
Thread.currentThread().hashCode());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 构造函数,每个线程都会执行一次。
TestClass() {
System.out.printf("TestClass object created in thread %d/n",
Thread.currentThread().hashCode());
}
}
执行结果:
Thread 6927154 enters static block. -- 后面等了两秒才继续输出
TestClass object created in thread 3043939
TestClass object created in thread 6927154
TestClass object created in thread 22540508
TestClass object created in thread 3043939
果然如此,static 块本身是同步的。