终于理解单列模式了,单列模式和多线程

1、单例类确保自己只有一个实例(构造方法私有化)
2、单例类必须自己创建自己的实例。
3、单例类必须为其他对象提供唯一的实例。
 

package Singleton;
//懒汉式  单例实例在第一次被使用时构建,延迟初始化。
public class singleton {
    private static singleton sing =null;    //1,表明这个类是不可能形成实例了。这主要是怕这个类会有多个实例。
    public static singleton getInstance(){    //2,即然这个类是不可能形成实例,那么,我们需要一个静态的方式让其形成实例:getInstance()
        if(sing==null){                        //3,在getInstance()中,先做判断是否已形成实例,如果已形成则直接返回,否则创建实例, 我们取实例时,只需要使用Singleton.getInstance()就行了。
            synchronized(singleton.class){//线程同步锁,必须等一个线程访问完,才能进行访问
                if(sing==null){//需要双重锁定,保证不会new两次
                sing=new singleton();//懒汉式:先初始化实例对象
                }
            }
        }
            return sing;
    }
    public void getName() {// 使用普通方法输出皇帝的名字
            System.out.println("单列模式:懒汉式");
        }
}


优点: 避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。
缺点: 懒汉式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。


饿汉式   在自己内部定义自己的一个实例,只供内部调用

public class Singleton1
{
    //2.提供一个全局访问点(其实就是一个全局静态字段),外部可以通过该字段访问该类的唯一实例
    //因为静态字段是属于类的,所以这样可以保证只有一个实例。
    private static final Singleton1 only = new Singleton1();//单例实例在类装载时就构建,急切初始化
    //1 将构造函数声明成私有的,这样可以确保在类的外部无法实例化该类(即在类的外部获取不到类的实例)
    private Singleton1() {//私有(private)的构造函数,表明这个类是不可能形成实例了, 解释:一个对象默认是存在一个隐式的带无参的构造方法,默认是public,所以在new一个对象时,默认调用的隐式的构造函数,当构造函数私有时就不能实例化对象。构造方法作用初始化,方法名和类名一样。创建对象都通过new
        //do something
    }
    //这里提供了一个供外部访问本class的静态方法,可以直接访问
    public static Singleton1 getInstance(){// 实例化引用
        return only;
    }
    //测试用方法
    public void put(){
        System.out.println("单列模式:饿汉式");
    }
   

}
 优点 1.线程安全
      2.在类加载的同时已经创建好一个静态对象,调用时反应速度快
 缺点
     资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化

 

public class test {
    
    public static void main(String[] args) {
        //将entry类的构造函数声明为私有的构造函数,这样我们在外部就无法通过Singleton s = new Singleton()来实例化该,因为Private生命的成员只有在该类的内部可以访问。这样可以保证类的实例只有一个(那就是在类的内部给它实例化)。
        singleton sing = singleton.getInstance();    
        singleton sing1 = singleton.getInstance();    
        System.out.println(sing.equals(sing1));//指向同一个对像
        sing.getName();//懒汉式实例对象输出
        sing1.getName();
        System.out.println("-----------------------------------------");
        
        Singleton1 s = Singleton1.getInstance();
        Singleton1 s1 = Singleton1.getInstance();
        s.put();//饿汉式实例对象输出
        s1.put();
        System.out.println(s.equals(s1));//指向同一个对像
        
    }



 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值