单例模式java中的几种写法和确保多线程下安全

来源:互联网 发布:手机游戏交易平台源码 编辑:程序博客网 时间:2024/04/29 11:48

单例模式的几种写法 ,单例设计模式就是所内存中之只加载一次。如何控制呢?下面给出几种实现

第一种懒汉式 延迟加载

package javaThreadandSinglon;/** * Created by Administrator on 2016/11/1. * 属于延迟加载 懒汉式 */public class Singlon {    private static Singlon instance;    private Singlon(){    }    public static Singlon getInstance(){        if(instance==null){            instance=new Singlon();        }        return instance;    }    public static void main(String [] args){        Singlon a = Singlon.getInstance();        Singlon b = Singlon.getInstance();        System.out.println(a.hashCode());        System.out.println(b.hashCode());    }}

结果是hashcode相同 是同一个对象

第一种饿汉式 立即加载

package javaThreadandSinglon;/** * Created by Administrator on 2016/11/1. */public class Singlon1 {    private static Singlon1 instance=new Singlon1();    private Singlon1(){    }    public static Singlon1 getInstance(){        return instance;    }    public static void main(String [] args){        Singlon a = Singlon.getInstance();        Singlon b = Singlon.getInstance();        System.out.println(a.hashCode());        System.out.println(b.hashCode());    }}
第三种实现静态内部类

package javaThreadandSinglon;/** * Created by Administrator on 2016/11/1. */public class Singlon2 {     private static class MyInStance{        private static Singlon2 singlon2=new Singlon2();    }    public static Singlon2 getInstance(){        return MyInStance.singlon2;    }    public static void main(String [] args){        Singlon2 a = Singlon2.getInstance();        Singlon2 b = Singlon2.getInstance();        System.out.println(a.hashCode());        System.out.println(b.hashCode());    }}
第四种用Static代码块实现

package javaThreadandSinglon;/** * Created by Administrator on 2016/11/1. */public class Singlon3 {    private static Singlon3 instance=null;    private Singlon3(){    }    static {        instance=new Singlon3();    }    public static Singlon3 getInstance(){        return instance;    }    public static void main(String [] args){        Singlon3 a = Singlon3.getInstance();        Singlon3 b = Singlon3.getInstance();        System.out.println(a.hashCode());        System.out.println(b.hashCode());    }}

第五种用enum枚举数据类型实现单例模式。

下面就上面代码的某些可能出现的线程安全给出改进方法,DCL处理懒汉模式 延迟加载 最优解决方案

package javaThreadandSinglon;/** * Created by Administrator on 2016/11/1. * 属于延迟加载 饿汉式 * 采用局部加锁 和双锁处理 */public class Singlon {    private volatile static Singlon instance;    private Singlon(){    }    public static Singlon getInstance(){       if(instance!=null){       }else {           synchronized(Singlon.class){               if(instance==null){                   instance=new Singlon();               }           }       }        return instance;    }}

package javaThreadandSinglon;/** * Created by Administrator on 2016/11/1. */public class TestTnread  extends Thread{    public void run(){        System.out.println(Singlon.getInstance().hashCode());    }}

package javaThreadandSinglon;/** * Created by Administrator on 2016/11/1. */public class Test {    public static void main(String [] args){       TestTnread t1=new TestTnread();        TestTnread t2=new TestTnread();        TestTnread t3=new TestTnread();        t1.start();        t2.start();        t3.start();    }}

静态内置类线程安全,但是遇到序列化对象也是存在线程安全的,下面给出解决方案, 饿汉线程安全

package javaThreadandSinglon;import java.io.Serializable;/** * Created by Administrator on 2016/11/1. */public class Singlon4 implements Serializable {    private static final long serial=888L;    private static class Singlon4Handle{        private static final Singlon4 instance=new Singlon4();    }    public static  Singlon4 getInstance(){        return Singlon4Handle.instance;    }}

package javaThreadandSinglon;import java.io.*;/** * Created by Administrator on 2016/11/1. */public class SaveAndRead {    public static void main(String [] args)  {        FileOutputStream fosref=null;        ObjectOutputStream oosref=null;        FileInputStream fieref=null;        ObjectInputStream iosref=null;        try {             Singlon4 instancs = Singlon4.getInstance();             fosref = new FileOutputStream(new File("myinstance.txt"));             oosref = new ObjectOutputStream(fosref);             oosref.writeObject(instancs);              System.out.println(instancs.hashCode());              fieref=new FileInputStream(new File("myinstance.txt"));              iosref=new ObjectInputStream(fieref);              Singlon4 instace1 = (Singlon4) iosref.readObject();              System.out.println(instace1.hashCode());        }catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        } finally {            if(iosref!=null){                try {                    iosref.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            if(fosref!=null){                try {                    fosref.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            if(fieref!=null){                try {                    fieref.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            if(oosref!=null){                try {                    oosref.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }}

结果展示



解决方案

加入一段代码

package javaThreadandSinglon;import java.io.ObjectStreamException;import java.io.Serializable;/** * Created by Administrator on 2016/11/1. */public class Singlon4 implements Serializable {    private static final long serial=888L;    private static class Singlon4Handle{        private static final Singlon4 instance=new Singlon4();    }    public static  Singlon4 getInstance(){        return Singlon4Handle.instance;    }    protected Object readResolve()throws ObjectStreamException{        System.out.println("该方法调用");        return Singlon4Handle.instance;    }}
然后测试代码不变结果是




0 0
原创粉丝点击