一、单例模式实现方式
常见的
1、饿汉方式
示例代码:
package com.mt.singleton;
/**
* 设计模式单例模式之饿汉实现方式
* 线程安全,调用效率高,但无法实现延迟加载
* @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;
}
}
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;
}
}
4、枚举实现方式
示例代码:
package com.mt.singleton;
/**
* 设计模式单例模式之枚举实现方式
* 线程安全,调用效率高,但没有实现延迟加载
* @author MT
*
*/
public enum SingletonDemo4 {
//定义一个枚举元素,枚举本身就是单例
INSTANCE;
//添加操作方法
public void instanceOperate(){
}
}
5、双重检查锁方式(很少用,不建议使用)
二、单例模式的防止反射和反序列化
package com.mt.singleton;
import java.io.ObjectStreamException;
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;
}
}
验证代码:
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 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);
}
}
总结:几种效率,懒汉方式最慢,因为懒汉实现了同步方法,有时候会涉及等待过程,其他三种都是差不多的,相对而言。
原文地址:https://www.cnblogs.com/MTAngel/p/10991308.html