我理解的单例设计模式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我理解的单例设计模式相关的知识,希望对你有一定的参考价值。
单例模式我们在开发中经常用到,但是我们可能熟知一种单例模式,但是单例模式也有好多种,现在就对几种单例模式做个比较,明白其中的优缺点:
- 单例代码:“饿汉式”,也就是当类加载进来的时候就创建实例,但是这种方式比较消耗资源。(单例模式的第一个版本)
public class Singleton{
private static Singleton single=new Singleton();
private Singleton(){
System.out.println("生成一个Singleton实例");
}
public static Singleton getInstance(){
return single;
}
}
2.测试代码
public class SingletonTest{
public static void main(String[] args){
System.out.println("Start...");
Singleton single1=Singleton.getInstance();
Singleton single2=Singleton.getInstance();
if(single1==single2){
System.out.println("obj1 和 obj2 是相同的实例。");
}else{
System.out.println("obj1 和 obj2 是不同的实例。");
}
System.out.println("End...");
}
}
3.测试结果
Start...
生成一个Singleton实例
obj1 和 obj2 是相同的实例。
End...
- 不是严格的Singleton模式的例子:“懒汉式”:单线程下可以,多线程下存在线程安全问题。(单例模式的第二个版本), 这段代码如果是在单线程中是没有什么问题的,但是因为没有锁的机制,在多线程中就会有问题,当同一时间有两个或者两个以上线程进入getInstance()方法时,因为刚开始single都是null , 几个线程都同时满足if(single==null) 这个条件,就会同时new Singleton() 这个对象
public class Singleton{
private static Singleton single=null;
private Singleton(){
System.out.println("生成一个Singleton实例");
}
public static Singleton getInstance(){
if(single==null){
single=new Singleton();
}
return single;
}
}
5.不是严格单例模式测试代码
public class SingletonThread implements Runnable {
private Set<Singleton> set=new HashSet<Singleton>();
@Override
public void run() {
Singleton single=Singleton.getInstance();
set.add(single);
System.out.println("Set的大小为:"+set.size()+","+set);
}
}
测试类Main方法
public class SingleTest {
public static void main(String[] args) {
SingletonThread t=new SingletonThread();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
}
6.测试结果:会看到会有多个“生成一个Singleton实例”,说明调用了5次 new Singleton()方法。
7.如果使用第一种方法的话:只会有一个“生成一个Singleton实例 ”,说明只调用了一次 new Singleton() 方法。
8.为了解决第二种多线程安全问题,采用对函数进行同步的方式,但是也比较浪费资源,因为每次都要进行同步检查,而实际真正需要检查的只是第一次。(单例模式的第三个版本)
public class Singleton{
private static Singleton single=null;
private Singleton(){
System.out.println("生成一个Singleton实例");
}
public static synchronized Singleton getInstance(){
if(single==null){
single=new Singleton();
}
return single;
}
}
运行结果:
9.(单例模式的第四个版本)既解决了“懒汉式”多线程的安全问题,又解决了浪费资源的现象。
public class Singleton{
private static Singleton single;
private Singleton(){
System.out.println("生成一个Singleton实例");
}
public static Singleton getInstance(){
if(single==null){
synchronized(Singleton.class) {
if(single==null) {
single=new Singleton();
}
}
}
return single;
}
}
运行结果:
10.单例模式优缺点总结:
优点:客户端使用单例模式的实例的时候,只需要调用一个单一的方法就可以得到一个唯一的实例,有利于节省资源。
缺点:首先单例模式很难实现实例化,这就导致采用单例模式的类很难被持久化,当然也很难通过网络进行传输;其次,由于单例采用静态方法,无法再继承结构中使用。
以上是关于我理解的单例设计模式的主要内容,如果未能解决你的问题,请参考以下文章