//最近海口出差,但学习还是要坚持。好几天没上CSDN了,有点想念。希望有一天,我也能天天敲代码。。。
//设计模式,不应该是模板,应该是编程思想,学习的本质,不在于记住她,而在于她触发了你的思想!
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
public class SingleTest {
public static void main(String[] args) throws Exception{
//==================1
SingleDemo sg=SingleDemo.getInstence();
SingleDemo sg1=SingleDemo.getInstence();
System.out.println(sg==sg1);
//==================2
/*SingleDemo01 sg2=SingleDemo01.getInstence();
SingleDemo01 sg21=SingleDemo01.getInstence();
System.out.println(sg2==sg21);*/
//=================3
SingleDemo03 sg3=SingleDemo03.getInstence();
SingleDemo03 sg31=SingleDemo03.getInstence();
System.out.println(sg3==sg31);
//====================
System.out.println(SingleDemo04.INSTENCE==SingleDemo04.INSTENCE);
SingleDemo04.INSTENCE.dowith();
//============通过反射 调用私有构造器
/*Class<SingleDemo01> cla=(Class<SingleDemo01>) Class.forName("mine.singleton.SingleDemo01");
Constructor<SingleDemo01> c=cla.getDeclaredConstructor(null);
c.setAccessible(true);
SingleDemo01 instence=c.newInstance();*/
//=======通过序列化 反序列化 创建多个实例
SingleDemo01 sg2=SingleDemo01.getInstence();
SingleDemo01 sg21=SingleDemo01.getInstence();
System.out.println(sg2);
//=================================
FileOutputStream fos=new FileOutputStream("D:/1.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(sg2);
oos.flush();
oos.close();
fos.close();
//=================================
FileInputStream fis=new FileInputStream(new File("D:/1.txt"));
ObjectInputStream ois=new ObjectInputStream(fis);
SingleDemo01 sss=(SingleDemo01) ois.readObject();
System.out.println(sss);
ois.close();
fis.close();
}
}
/**
* 单例模式:饿汉式
* 线程安全 调用效率高
*
*/
class SingleDemo{
//类加载时 天然的线程安全。立即加载,不延时。可能会浪费资源
private static SingleDemo instence=new SingleDemo();
private SingleDemo(){
}
public static SingleDemo getInstence(){
return instence;
}
}
/**
* 单例模式:懒汉式
* 延时加载 ,真正用的时候才加载。
* 资源利用率高
* 同步方法,并发效率低
*/
class SingleDemo01 implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
//延时加载,真正用的时候 再加载
private static SingleDemo01 instence;
private SingleDemo01(){
if(null!=instence){//防止 反射调用 构造器。写项目一般不需要这样考虑
throw new RuntimeException();
}
}
//方法同步,调用效率低
public static synchronized SingleDemo01 getInstence(){
if(instence==null){
instence=new SingleDemo01();
}
return instence;
}
//==========防止反序列化,生成多个实例
public Object readResolve(){
return instence;
}
}
/**
* 单例模式:双重检测锁
* 由于编译器优化,与jvm底层模型的问题,偶尔会出问题,不建议使用
*/
class SingleDemo02{
private static SingleDemo02 instence;
private SingleDemo02(){}
public static SingleDemo02 getInstence(){
if(instence==null){
SingleDemo02 sg;
synchronized(SingleDemo02.class){
sg=instence;
if(sg==null){
synchronized(SingleDemo02.class){
if(sg==null){
sg=new SingleDemo02();
}
}
return sg;
}
}
}
return instence;
}
}
/**
* 单例模式:静态内部类
* 兼具:并发高效,延时加载,
* 线程安全
* 外部类 没有static属性,所以不会像饿汉式直接加载
*/
class SingleDemo03{
private static class SingleInstence{
//instence是 static final 类型保证了只有这样一个实例存在,而且只能赋值一次,保证线程安全
private static final SingleDemo03 instence=new SingleDemo03();
}
private SingleDemo03(){
}
public static SingleDemo03 getInstence(){
return SingleInstence.instence;
}
}
/**
* 单例模式:枚举
* 没有懒加载
* 避免了 序列化反序列化和反射的漏洞
*/
enum SingleDemo04{
INSTENCE;
//==================
public void dowith(){
System.out.println("我是枚举类型的单实例");
}
}