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

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

第一种懒汉式 延迟加载

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;
    }
}
然后测试代码不变结果是




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值