1 e汉 (优:没有同步开销 缺:不使用时会进行初始化-消耗资源)
public class Single{
private static final Single mSingle = new Single;
private Single(){}
public static Single getSingle(){
return mSingle;
}
}
2 懒汉----(优:使用时实例化-节约资源 缺:首次加载实例化,反应稍慢 最大问题:每次获取都同步造成不必要的同步开销)
public class Single{
private static Single mSingle;
private Single(){}
public static synchronized Single getSingle(){
if(mSingle == null){
mSingle = new Single();
}
return mSingle;
}
}
3 双重锁(优:既能需要时才实例化,又保证线程安全,对象实例化后不进行同步锁 缺:第一次加载慢,高并发有缺陷)(优化缺陷,不建议使用)
public class Single{
private static Single mSingle = null;
private Single(){}
public static Single getSingle(){
if(mSingle == null){
synchronized(Single.class){
if(mSingle == null){
mSingle = new Single();
}
}
mSingle = new Single();
}
return mSingle;
}
}
4 静态内部类实现单例(优:延迟加载,线程安全 缺:)(推荐使用-感觉很像e汉)?
public class Single{
private Single(){}
public static Single getSingle(){
return SingleHolder.mSingle;
}
//静态内部类
private static class SingleHolder{
private static final Single mSingle = new Single();
}
}
5 枚举单列
-------拓展静态代码块,静态变量,静态内部类初始化时期 下文原址链接
关于这个问题,本文不扯理论,直接上代码,通过结果来验证结论,废话少说,测试代码如下:
public class StaticTest {
public static StaticMember staticMember = new StaticMember();
static {
System.out.println("static code initializer ");
}
private static class InnerClass {
private static StaticTest staticTest = new StaticTest("load from InnerClass");
}
public StaticTest() {
}
public StaticTest(String a) {
System.out.println(a);
}
public static void f(){
}
public void d(){
}
public static void e(){
InnerClass.staticTest.d();
}
}
在StaticTest 测试类中我写了三种静态域分别是静态成员变量,静态代码块以及静态内部类,下面通过不同的case测试上面三种静态域何时被初始化。
测试case代码:
public class Main {
static boolean flg;
public static void main(String[] args) {
/**case1**/
//不会执行静态代码块, 静态成员变量不会初始化, 也不会加载静态内部类
String simpleName = StaticTest.class.getSimpleName();
/**case2**/
//会执行静态代码块, 静态成员变量会初始化, 不会加载静态内部类
//输出 StaticMember
// static code initializer
StaticMember staticMember = StaticTest.staticMember;
/**case3**/
//会执行静态代码块, 静态成员变量会初始化, 不会加载静态内部类
//输出 StaticMember
// static code initializer
new StaticTest();
/**case4**/
//会执行静态代码块, 静态成员变量会初始化, 不会加载静态内部类
//输出 StaticMember
// static code initializer
StaticTest.f();
/**case5**/
//不会执行静态代码块, 静态成员变量不会初始化, 也不会加载静态内部类
if (flg) {
test();
}
/**case6**/
//会执行静态代码块, 静态成员变量会初始化, 同时加载静态内部类
// 输出:StaticMember
// static code initializer
// load from InnerClass
StaticTest.e();
}
private static void test(){
StaticTest.f();
StaticTest.e();
}
}