新手区 每周一算法--单例模式

icerman · 2018年06月09日 · 最后由 a379611523 回复于 2018年06月11日 · 924 次阅读

-------------------------------------------------java方式----------------------------------------------------------------------------------

package algurimProject;
public class SingleClass {  

//懒汉模式,线程不安全
    public static class Singleton{
        private static Singleton singleton = null;
        private Singleton() {

        }
        public static Singleton getSingleton() {
            if(singleton ==null) {
                singleton = new Singleton();
            }
            return singleton;
        }   
    }

    //饿汉模式,线程安全
    public static class Singleton2{
        private static Singleton2 singleton2 = new Singleton2();
        private Singleton2() {

        }
        public static Singleton2 getSingleton2(){
            return singleton2;
        }
    }


    // 懒汉模式,线程安全模式
    public static class Singleton3{
        private static Singleton3 singleton3 = null;
        private Singleton3() {

        }
        public static synchronized Singleton3 getSingleton3() {
            if(singleton3 ==null) {
                singleton3 = new Singleton3();
            }
            return singleton3;
        }
    }


    /** 
     * 静态内部类,使用双重校验锁,线程安全【推荐】 
     */  
    public static class Singleton4 {  
        private volatile static Singleton4 instance = null;  

        private Singleton4() {  

        }  

        public static Singleton4 getInstance() {  
            if (instance == null) {  
                synchronized (Singleton4.class) {  
                    if (instance == null) {  
                        instance = new Singleton4();  
                    }  
                }  
            }  

            return instance;  
        }  
    }  


    /** 
     * 单例模式,使用静态内部类,线程安全【推荐】 
     */  
    public static class Singleton5 {  
        private final static class SingletonHolder {  
            private static final Singleton5 INSTANCE = new Singleton5();  
        }  

        private Singleton5() {  

        }  

        public static Singleton5 getInstance() {  
            return SingletonHolder.INSTANCE;  
        }  
    }  
}

-------------------------------------------------python方式----------------------------------------------------------------------------------


# 用__new__实现
class SingleClass(object):
    __instance = None
    __first_init = None

    def __new__(cls, age, name):
        if not cls.__instance:
            SingleClass.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self, age, name):
        if not self.__first_init:
            self.age = age
            self.name = name
            SingleClass.__first_init = True

a = SingleClass(21, "jatrix")
b = SingleClass(2, "jatrix")

print(id(a))
print(id(b))
print(a.age)
print(b.age)

a.age = 33
print(b.age)

# 使用注解的方式
def singleton(cls, *args, **kwargs):
    instance = {}

    def __singleton():
        if cls not in instance:
            instance[cls] = cls
        return instance[cls]

    return __singleton


@singleton
class MyClass:
    kind = "type"

    def __init__(self, name):
        self.name = name


@singleton
class MyAnotherClass:
    name = "another"

    def __init__(self, age):
        self.age = age


one = MyClass()
two = MyClass()
print(id(one))
print(id(two))


another_one = MyAnotherClass()
another_two = MyAnotherClass()
print(id(another_one))
print(id(another_two))
共收到 10 条回复 时间 点赞

根据自己的理解总结一下:
1、懒汉模式,需要用到的时候再实例化对象,开始比较节省资源,但是在多线程环境下可能会出现重复创建多个对象的可能,所以多线程环境一定要考虑加锁。
2、饿汉模式,在一开始直接造一个对象,好处避免了多线程重复创造对象的问题,但是开始就创造对象不一定会被用上,比较占服务器资源。

124446339 回复

单例模式就是为了避免不一致状态的,所以单例类只能有一个实例,而且是唯一实例。
那就不可能再多线程环境下创建多个对象了

//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
    private static class LazyHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton() {}
//静态工厂方法
    public static final Singleton getInstance() {
        return LazyHolder.INSTANCE;
    }
}
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
    private Singleton1() {}
    private static final Singleton1 single = new Singleton1();
    //静态工厂方法
    public static Singleton1 getInstance() {
        return single;
    }
}
zailushang 回复

多个对象指的是第一个例子。。在多线程环境下,可能有许多个线程同时判断singleton ==null,然后一直new,会造成资源浪费,虽然singleton到最后只会指向一个实例吧。

124446339 回复

懒汉模式:只在第一次调用的时候初始化,因为getInstance()方法返回值是static final类型,静态常量类型,所以后期就算引用Singleton,也不会new出新的对象来(因为Singleton类的构造函数是私有的,只有自己类能访问,别的类都不能访问,怎么可以new空的对象呢?)

zailushang 回复

我说的是他这个文章的第一个例子。。。。。。

124446339 回复

他那个例子不够好,不属于单例模式吧,至少在面试官看来,应该是不合格的单例

zailushang 回复

嗯嗯。看得出来他举得例子是个循序渐进的关系,不过你讲的一些东西我的确也是涨到姿势了,十分感谢。

124446339 回复

客气啦,我也是在学习中,互相学习

public class SingleClass
{
    public static SingleClass Single { get; } = new SingleClass();

    private SingleClass()
    {

    }//SingleClass()

}//class SingleClass

java单例还有最好的方式你没写,枚举实现单例

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册