设计模式学习之单例模式
Posted mtangel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式学习之单例模式相关的知识,希望对你有一定的参考价值。
一、单例模式实现方式
常见的
1、饿汉方式
示例代码:
package com.mt.singleton;
/**
* 设计模式单例模式之饿汉实现方式
* 线程安全,调用效率高,但无法实现延迟加载
* @author MT
*
*/
public class SingletonDemo1
private static SingletonDemo1 s = new SingletonDemo1();
//私有化构造器
private SingletonDemo1()
//添加获取对象的公共方法,不能延迟加载
public static SingletonDemo1 getInstance()
return s;
/**
* 设计模式单例模式之饿汉实现方式
* 线程安全,调用效率高,但无法实现延迟加载
* @author MT
*
*/
public class SingletonDemo1
private static SingletonDemo1 s = new SingletonDemo1();
//私有化构造器
private SingletonDemo1()
//添加获取对象的公共方法,不能延迟加载
public static SingletonDemo1 getInstance()
return s;
2、懒汉方式
示例代码:
package com.mt.singleton;
/**
* 设计模式单例模式之懒汉实现方式
* 线程安全,延迟加载,但调用效率不高
* @author MT
*
*/
public class SingletonDemo2
private static SingletonDemo2 s;
//私有化构造器
private SingletonDemo2()
//添加获取对象的公共方法,同步方法,所以调用效率低,实现延迟加载
public static synchronized SingletonDemo2 getInstance()
if (s==null)
s=new SingletonDemo2();
return s;
/**
* 设计模式单例模式之懒汉实现方式
* 线程安全,延迟加载,但调用效率不高
* @author MT
*
*/
public class SingletonDemo2
private static SingletonDemo2 s;
//私有化构造器
private SingletonDemo2()
//添加获取对象的公共方法,同步方法,所以调用效率低,实现延迟加载
public static synchronized SingletonDemo2 getInstance()
if (s==null)
s=new SingletonDemo2();
return s;
3、静态内部类方式
示例代码:
package com.mt.singleton;
/**
* 设计模式单例模式之静态内部类实现方式
* 线程安全,调用效率高,实现了延迟加载
* @author MT
*
*/
public class SingletonDemo3
//静态内部类
private static class InnerClass
private static final SingletonDemo3 sc=new SingletonDemo3();
//私有化构造器
private SingletonDemo3()
//添加获取对象的公共方法,实现延迟加载
public static SingletonDemo3 getInstance()
return InnerClass.sc;
/**
* 设计模式单例模式之静态内部类实现方式
* 线程安全,调用效率高,实现了延迟加载
* @author MT
*
*/
public class SingletonDemo3
//静态内部类
private static class InnerClass
private static final SingletonDemo3 sc=new SingletonDemo3();
//私有化构造器
private SingletonDemo3()
//添加获取对象的公共方法,实现延迟加载
public static SingletonDemo3 getInstance()
return InnerClass.sc;
4、枚举实现方式
示例代码:
package com.mt.singleton;
/**
* 设计模式单例模式之枚举实现方式
* 线程安全,调用效率高,但没有实现延迟加载
* @author MT
*
*/
public enum SingletonDemo4
//定义一个枚举元素,枚举本身就是单例
INSTANCE;
//添加操作方法
public void instanceOperate()
/**
* 设计模式单例模式之枚举实现方式
* 线程安全,调用效率高,但没有实现延迟加载
* @author MT
*
*/
public enum SingletonDemo4
//定义一个枚举元素,枚举本身就是单例
INSTANCE;
//添加操作方法
public void instanceOperate()
5、双重检查锁方式(很少用,不建议使用)
二、单例模式的防止反射和反序列化
package com.mt.singleton;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.io.Serializable;
/**
* 设计模式单例模式之饿汉实现方式
* 线程安全,调用效率高,但无法实现延迟加载
* @author MT
*
*/
public class SingletonDemo6 implements Serializable
private static SingletonDemo6 s = new SingletonDemo6();
//私有化构造器
private SingletonDemo6()
if (s!=null)
throw new RuntimeException();
//添加获取对象的公共方法,不能延迟加载
public static SingletonDemo6 getInstance()
return s;
public Object readResolve() throws ObjectStreamException
return s;
* 设计模式单例模式之饿汉实现方式
* 线程安全,调用效率高,但无法实现延迟加载
* @author MT
*
*/
public class SingletonDemo6 implements Serializable
private static SingletonDemo6 s = new SingletonDemo6();
//私有化构造器
private SingletonDemo6()
if (s!=null)
throw new RuntimeException();
//添加获取对象的公共方法,不能延迟加载
public static SingletonDemo6 getInstance()
return s;
public Object readResolve() throws ObjectStreamException
return s;
验证代码:
package com.mt.test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import com.mt.singleton.SingletonDemo6;
/**
* 单例模式(防止反射和反序列化)
* @author MT
*
*/
public class Client
public static void main(String[] args) throws Exception
SingletonDemo6 s1=SingletonDemo6.getInstance();
SingletonDemo6 s2=SingletonDemo6.getInstance();
System.out.println(s1);
System.out.println(s2);
/* //防止反射
//获取类对象
Class<SingletonDemo6> clazz = (Class<SingletonDemo6>) Class.forName("com.mt.singleton.SingletonDemo6");
//获取构造器对象
Constructor<SingletonDemo6> c = clazz.getDeclaredConstructor(null);
//访问私有化构造器
c.setAccessible(true);
SingletonDemo6 s3 = c.newInstance();
SingletonDemo6 s4 = c.newInstance();
System.out.println(s3);
System.out.println(s4);*/
//防止反序列化
FileOutputStream os = new FileOutputStream("D:/a.txt");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(s1);
oos.close();
os.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/a.txt"));
SingletonDemo6 s3 = (SingletonDemo6) ois.readObject();
System.out.println(s3);
* 单例模式(防止反射和反序列化)
* @author MT
*
*/
public class Client
public static void main(String[] args) throws Exception
SingletonDemo6 s1=SingletonDemo6.getInstance();
SingletonDemo6 s2=SingletonDemo6.getInstance();
System.out.println(s1);
System.out.println(s2);
/* //防止反射
//获取类对象
Class<SingletonDemo6> clazz = (Class<SingletonDemo6>) Class.forName("com.mt.singleton.SingletonDemo6");
//获取构造器对象
Constructor<SingletonDemo6> c = clazz.getDeclaredConstructor(null);
//访问私有化构造器
c.setAccessible(true);
SingletonDemo6 s3 = c.newInstance();
SingletonDemo6 s4 = c.newInstance();
System.out.println(s3);
System.out.println(s4);*/
//防止反序列化
FileOutputStream os = new FileOutputStream("D:/a.txt");
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(s1);
oos.close();
os.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/a.txt"));
SingletonDemo6 s3 = (SingletonDemo6) ois.readObject();
System.out.println(s3);
总结:几种效率,懒汉方式最慢,因为懒汉实现了同步方法,有时候会涉及等待过程,其他三种都是差不多的,相对而言。
以上是关于设计模式学习之单例模式的主要内容,如果未能解决你的问题,请参考以下文章