论坛首页 Java企业应用论坛

非线程同步机制下线程安全的单例模式——最优的单例模式

浏览 15270 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-18  
lyy3323 写道
nianien 写道
zhang34082 写道
第三种与第一种 是一样的机制,都是通过静态块来初始化的

怎么能是一样的呢?
都说了实例化的时间不一样
第一种,只要你第一次引用了类,都会触发单例对象的实例化
而第三种,只要你不去调用getInsance方法,是不永远不会实例化单例对象的

static是什么?哪来的延迟。

真是服了你了,你知道static有哪些用处么?
0 请登录后投票
   发表时间:2011-05-18  
一个静态内部类,纠结甚!
0 请登录后投票
   发表时间:2011-05-18  
sswh,bingo!

可以结贴了。
0 请登录后投票
   发表时间:2011-05-18  
引用
Java代码 
1.public class SingleTon {  
2.    private static SingleTon s = new SingleTon();  
3. 
4.    public static SingleTon getInstance() {  
5.        return s;  
6.    }  
7. 
8.    static {  
9.        System.out.println("悲催了,被加载了!");  
10.    }  
11. 
12.    private SingleTon() {  
13.        System.out.println("悲催了,被实例化了!");  
14.    }  
15.}  
16. 
17.public class Test {  
18. 
19.    public static void main(String[] args) throws ClassNotFoundException {  
20.        Class.forName("my.SingleTon", false, Test.class.getClassLoader());  
21.        System.out.println("做点其他事情...");  
22.        SingleTon.getInstance();  
23.    }  
24.} 
public class SingleTon {
private static SingleTon s = new SingleTon();

public static SingleTon getInstance() {
return s;
}

static {
System.out.println("悲催了,被加载了!");
}

private SingleTon() {
System.out.println("悲催了,被实例化了!");
}
}

public class Test {

public static void main(String[] args) throws ClassNotFoundException {
Class.forName("my.SingleTon", false, Test.class.getClassLoader());
System.out.println("做点其他事情...");
SingleTon.getInstance();
}
}


Test类main方法的第一行加载SingleTon类,但不会初始化SingleTon。
SingleTon类被初始化是 直到调用SingleTon.getInstance();方法的时候。
所以,这种方法也是具有延迟加载效果的。

这个受教了,但是这个也只是对Class.forName有用吧,
一旦你调用了该类的其他方法或者引用该类信息的时候就会实例化吧?
0 请登录后投票
   发表时间:2011-05-18  
zhouxianglh 写道
一个静态内部类,纠结甚!

何来纠结,只是讨论延迟加载的问题~
0 请登录后投票
   发表时间:2011-05-18  
sswh 写道
nianien 写道
下面这种单例模式是应用最多的,同样不存在线程同步的问题
但是,不能实现延迟实例化
引用

public class SingleTon {
private SingleTon(){}
         private static SingleTon s=new SingleTon();
public static SingleTon getInstance() {
return s;
}
}



这种单例模式,和上面的实现差不多,虽然能够延迟单例对象的实例化,但是都是在同一时间范围内完成的
引用

public class SingleTon {
private SingleTon(){}
private static SingleTon s;
static {
s=new SingleTon();
}
public static SingleTon getInstance() {
return s;
}
}


上下两份代码编译后的字节码一模一样

何来上面一种“但是,不能实现延迟实例化
而下面一种“虽然能够延迟单例对象的实例化

也就是说:
         private static SingleTon s=new SingleTon();


完全等价于:
	private static SingleTon s;
	static {
		s=new SingleTon();
	}


静态变量的初始化发生在  类被加载的时候(缺省情况下,被加载的类会在加载时被初始化,除非明确指定延迟初始化),
    public static Class<?> forName(String name, boolean initialize, ClassLoader loader)



声明一下,这里讲延迟加载,就是你不显示call 实例的时候,不会实例化,至于你调其他方法什么的,木有关系
0 请登录后投票
   发表时间:2011-05-18  
nianien 写道
引用
Java代码 
1.public class SingleTon {  
2.    private static SingleTon s = new SingleTon();  
3. 
4.    public static SingleTon getInstance() {  
5.        return s;  
6.    }  
7. 
8.    static {  
9.        System.out.println("悲催了,被加载了!");  
10.    }  
11. 
12.    private SingleTon() {  
13.        System.out.println("悲催了,被实例化了!");  
14.    }  
15.}  
16. 
17.public class Test {  
18. 
19.    public static void main(String[] args) throws ClassNotFoundException {  
20.        Class.forName("my.SingleTon", false, Test.class.getClassLoader());  
21.        System.out.println("做点其他事情...");  
22.        SingleTon.getInstance();  
23.    }  
24.} 
public class SingleTon {
private static SingleTon s = new SingleTon();

public static SingleTon getInstance() {
return s;
}

static {
System.out.println("悲催了,被加载了!");
}

private SingleTon() {
System.out.println("悲催了,被实例化了!");
}
}

public class Test {

public static void main(String[] args) throws ClassNotFoundException {
Class.forName("my.SingleTon", false, Test.class.getClassLoader());
System.out.println("做点其他事情...");
SingleTon.getInstance();
}
}


Test类main方法的第一行加载SingleTon类,但不会初始化SingleTon。
SingleTon类被初始化是 直到调用SingleTon.getInstance();方法的时候。
所以,这种方法也是具有延迟加载效果的。

这个受教了,但是这个也只是对Class.forName有用吧,
一旦你调用了该类的其他方法或者引用该类信息的时候就会实例化吧?


调用静态方法或属性不用实例化。
调用对象方法或属性肯定要实例化。
0 请登录后投票
   发表时间:2011-05-18  
nianien 写道
lyy3323 写道
nianien 写道
zhang34082 写道
第三种与第一种 是一样的机制,都是通过静态块来初始化的

怎么能是一样的呢?
都说了实例化的时间不一样
第一种,只要你第一次引用了类,都会触发单例对象的实例化
而第三种,只要你不去调用getInsance方法,是不永远不会实例化单例对象的

static是什么?哪来的延迟。

真是服了你了,你知道static有哪些用处么?


wo kao,刚开始没看清楚,你定义了以个静态的内部类。。。。

你这做法? 通过牺牲初始化内部类达到延迟加载单列类???
0 请登录后投票
   发表时间:2011-05-18  
lyy3323 写道
nianien 写道
lyy3323 写道
nianien 写道
zhang34082 写道
第三种与第一种 是一样的机制,都是通过静态块来初始化的

怎么能是一样的呢?
都说了实例化的时间不一样
第一种,只要你第一次引用了类,都会触发单例对象的实例化
而第三种,只要你不去调用getInsance方法,是不永远不会实例化单例对象的

static是什么?哪来的延迟。

真是服了你了,你知道static有哪些用处么?


wo kao,刚开始没看清楚,你定义了以个静态的内部类。。。。

你这做法? 通过牺牲初始化内部类达到延迟加载单列类???



说错,确实是达到延迟加载。只不过看出去有点怪。

0 请登录后投票
   发表时间:2011-05-18  
lyy3323 写道
lyy3323 写道
nianien 写道
lyy3323 写道
nianien 写道
zhang34082 写道
第三种与第一种 是一样的机制,都是通过静态块来初始化的

怎么能是一样的呢?
都说了实例化的时间不一样
第一种,只要你第一次引用了类,都会触发单例对象的实例化
而第三种,只要你不去调用getInsance方法,是不永远不会实例化单例对象的

static是什么?哪来的延迟。

真是服了你了,你知道static有哪些用处么?


wo kao,刚开始没看清楚,你定义了以个静态的内部类。。。。

你这做法? 通过牺牲初始化内部类达到延迟加载单列类???



说错,确实是达到延迟加载。只不过看出去有点怪。



呵呵,大家都很热衷技术啊,好现象~

我个人认为带懒加载的最优单例模式是楼主说的第二种,不知大家认为如何。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics