1.饿汉式
package study.singleModel;
/**
* 饿汉式
* 就是在类加载的时候就创建实例
* @author an
*
*/
public class HungerSingle {
private HungerSingle(){}
private static HungerSingle hs = new HungerSingle();
public static HungerSingle getInstance(){
return hs;
}
public static void main(String[] args) {
HungerSingle hs = HungerSingle.getInstance();
HungerSingle hs1 = HungerSingle.getInstance();
System.out.println(hs==hs1);
}
}
2.懒汉式
package study.singleModel;
/**
* 懒汉式
* 在需要使用的时候再创建实例,多线程的条件下会有线程安全问题
* @author an
*
*/
public class LazySingle {
private LazySingle(){}
private static LazySingle ls = null;
//线程安全的加上synchronized
public static LazySingle getInstance(){
if(ls==null){
synchronized(LazySingle.class){
if(ls==null){
ls = new LazySingle();
}
}
}
return ls;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
for(int i=0;i<1000000000;i++){
LazySingle.getInstance();
}
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
3.静态内部类
package study.singleModel;
/**
* 静态内部类
* 静态内部类可以比懒汉线程安全的模式有更好的效率,序列化对象的时候会创建多例
* @author an
*
*/
public class InnerClassSingle {
private InnerClassSingle(){}
private static class InnerClassSingleModel{
private static InnerClassSingle inn = new InnerClassSingle();
}
public static InnerClassSingle getInstance(){
return InnerClassSingleModel.inn;
}
public static void main(String[] args) {
InnerClassSingle is = InnerClassSingle.getInstance();
InnerClassSingle is1 = InnerClassSingle.getInstance();
System.out.println(is1==is);
}
}
4.能序列化的单例
package study.singleModel;
import java.io.Serializable;
/**
* 序列化
* @author an
*
*/
public class SerialSingle implements Serializable{
private static final long serialVersionUID = 5689953910494198711L;
private SerialSingle(){
}
private static SerialSingle ss = new SerialSingle();
public static SerialSingle getInstance(){
return ss;
}
private Object readResolve(){
return ss;
}
}
package study.singleModel;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerialTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerialSingle s1 = null;
SerialSingle s = SerialSingle.getInstance();
FileOutputStream fos = null;
ObjectOutputStream oos = null;
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fos = new FileOutputStream("SerialSingle.obj");
oos = new ObjectOutputStream(fos);
oos.writeObject(s);
} finally {
oos.flush();
oos.close();
fos.close();
}
try{
fis = new FileInputStream("SerialSingle.obj");
ois = new ObjectInputStream(fis);
s1 = (SerialSingle) ois.readObject();
}finally{
ois.close();
fis.close();
}
System.out.println(s);
System.out.println(s1);
System.out.println(s == s1);
}
}
5.单例模式防止反射入侵
package study.singleModel;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* 单例模式的反射防侵入
* @author an
*
*/
public class ReflectSingle {
private static boolean flag=true;
private ReflectSingle(){
synchronized (this) {
if(flag){
flag = false;
}else{
throw new RuntimeException("单例模式被侵犯!");
}
}
}
private static class InnerClassReflect{
private static ReflectSingle RS = new ReflectSingle();
}
public ReflectSingle getInstance(){
return InnerClassReflect.RS;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
Class<?> clas = ReflectSingle.class;
Constructor<?> c = clas.getDeclaredConstructor();
c.setAccessible(true);
ReflectSingle rs1 = (ReflectSingle)c.newInstance(null);
Field nameField = clas.getDeclaredField("flag");// 获取私有成员变量:name
nameField.setAccessible(true);// 设置操作权限为true
nameField.setBoolean(rs1, true);
ReflectSingle rs2 = (ReflectSingle)c.newInstance(null);
System.out.println(rs1==rs2);
}
}
6.枚举类实现单例
package study.singleModel;
/**
* 要创建单例的类
* @author an
*
*/
public class EnumSingleModel {
public void say(){
System.out.println("我是EnumSingleModel");
}
}
package study.singleModel;
/**
* 枚举类
* 枚举类是用来共享的
* enum实现单例有三个特性,自由序列化,线程安全,保证单例
* @author an
*
*/
public enum EnumSingle {
DATASOURCE;
private EnumSingleModel connection = null;
private EnumSingle() {
connection = new EnumSingleModel();
}
public EnumSingleModel getSingleModel() {
return connection;
}
}
package study.singleModel;
public class EnumSingleTest {
public static void main(String[] args) {
EnumSingleModel e1 = EnumSingle.DATASOURCE.getSingleModel();
EnumSingleModel e2 = EnumSingle.DATASOURCE.getSingleModel();
e1.say();
System.out.println(e1==e2);
}
}