JavaSE基础自学---单例设计模式

单例设计模式(饿汉式)(懒汉式)

单例设计模式:解决一个类在内存中只能存在一个对象

  • 禁止其他程序创建该类对象 (将构造函数私有化)
  • 为了让其他程序可以访问该对象,在本类创建唯一对象 (在类中new一个对象)
  • 提供对外访问方法,让外部可以访问自定义的对象 (提供方法获取自定义对象)

应用场景:

  • 统计当前在线人数(网站计数器):用一个全局对象来记录。
  • 打印机(设备管理器):当有两台打印机,在输出同一个文件的时候只一台打印机进行输出。
  • 数据库连接池(控制资源):一般是采用单例模式,因为数据库连接是一种连接数据库资源,不易频繁创建和销毁。
  • 数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率的损耗还是非常昂贵的,因此用单例模式来维护,就可以大大降低这种损耗。
  • 配置文件(共享数据),例如更改软件背景颜色,再次打开这软件背景颜色不变

饿汉式:

这种方式不会产生线程安全问题,因为在JVM中,对类的加载和类初始化,由虚拟机保证线程安全。
优点:没有加锁,执行效率会提高。
缺点:可能有时候不需要使用,会浪费内存,如果这个对象很大时,更会影响内存占用。

public class Single1 {
    //饿汉式

    //1,将构造函数私有化,外部就不可以创建对象
    private Single1(){

    }

    //2,本类中自定义一个对象
    private static Single1 s=new Single1();

    //3,static修饰获取 S 对象,不能new对象,则不能使用对象调用此功能,所以需要使用类名调用,必须static
    public static Single1 getInstance(){
        return s;
    }
}

懒汉式:

对象在方法被调用时才被创建/对象的延时加载

 class Single2 {
    //懒汉式
    private Single2(){

    }
    private static Single2 s=null;

    public static Single2 getInstance(){  //线程不安全写法
        if (s==null){
            s=new Single2();
        }
        return s;
    }
}
  public static synchronized Single2 getInstance(){  //懒汉式线程安全写法
        if (s==null){
            s=new Single2();
        }
        return s;
    }

在多线程单例模式下,懒汉式容易出现问题;
两个线程都执行该对象

当线程A执行完 (s = =null) 后,没有继续执行,CPU切换线程B执行,B也执行了 (s= =null) 和(s=new Single2() ),创建了一个该类的对象. CPU切回到线程A.这时线程A也会执行 (s=new Single2() ).又创建了该类对象.导致了唯一性错误.

synchronized : 可以优化以上问题.当线程A执行getInstance() ,其他线程只能执行到synchronized (Single2.class) 前的程序


懒汉式优化(双重判空)

使用 synchronized 保证线程在创建对象的时候让其他线程阻塞

 class Single2 {
    //懒汉式优化
    private Single2(){
    }
    private static Single2 s=null;
    public static Single2 getInstance(){
        if (s==null){
        
            synchronized (Single2.class){
            
                if (s==null){
                    s=new Single2();
                }
            }
        } return s;
    }
}


简单实例演示-----

class ColorSet{
    private String Color="灰色";

    public void setColor(String Color){  //设置颜色
        this.Color=Color;
    }
    public String getColor(){       //获取颜色
        return Color;
    }

    private ColorSet(){      //私有构造函数,禁止new对象

    }

    private static ColorSet c=new ColorSet();  //类中new唯一对象

    public static ColorSet getNew(){      //获取唯一对象
        return  c;
    }
}

public class DEMO {

    public static void main(String[] args) {
        ColorSet c1= ColorSet.getNew();
        System.out.println("默认颜色= "+c1.getColor());

        c1.setColor("蓝色");
        System.out.println("修改后颜色="+c1.getColor());

        ColorSet c2 =ColorSet.getNew();
        System.out.println("c2颜色="+c1.getColor());
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值