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

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

-------------------------------------------------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单例还有最好的方式你没写,枚举实现单例

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