类构造函数clinit尽量简单化
java的类构造方法只能执行一次(不考虑多个类加载器和类卸载的情况),由jvm隐式加锁保护完成。
因此,在clinit方法的实现时,要尽量简单,避免复杂的操作,尤其是加锁的操作,避免monitor lock和clinit的隐式锁构成死锁。
以下是一些验证代码。
import org.junit.Test;class User { //一个类的clinit方法只能执行一次(不考虑多个类加载器和类卸载的情况),由jvm加锁保护。 static { System.out.println("User's clinit start."); try { Thread.sleep(10000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("User's clinit end."); }}public class Example { @Test public void test() throws Exception { final Thread t1 = new Thread(new Runnable() { public void run() { User user = new User(); System.out.println("t1 done with " + user); } }); //clinit的锁和class object的monitor lock无关。 final Thread t2 = new Thread(new Runnable() { public void run() { synchronized (User.class) { System.out.println("t2 done"); } } }); //clinit只能执行一次,并且有锁保护。 final Thread t3 = new Thread(new Runnable() { public void run() { User user = new User(); System.out.println("t3 done with " + user); } }); t1.start(); Thread.sleep(2000); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); }}