单例模式(redo)

new 函数在 **init 之前调用。一般用于子类定制父类内容,可一般用于修改不可变实例的内容,如 tuple, int, str, float,因为这些对象,一旦实例化就不可以被修改。**一般情况下,覆写 new() 的实现将会使用合适的参数调用其超类的 super().new(),并在返回之前修改实例。

class nonZero(int):
    def __new__(cls,value):
        return super().__new__(cls,value) if value != 0 else None
    def __init__(self,skipped_value):
        #此例中会跳过此方法
        print("__init__()")
        super().__init__()
print(type(nonZero(-12)))
print(type(nonZero(0)))

init, new 返回的对象不是当前类的实例,__init__不会被调用。

def **new(cls, *args, kwargs) :

注意: 用 super().new 来创建实例。

Python

类内元素要通过, cls. 获取

import time
from threading import Thread, Lock
lock = Lock()
class Singleton():
    _instance = None
    def __new__(cls):
        if cls._instance != None:
            return cls._instance
        with lock:
            if cls._instance == None:
                time.sleep(0.05)
                cls._instance = super().__new__(cls)
            return cls._instance
        

def create():
    obj = Singleton()
    print(id(obj))
    

for i in range(10):
    t = Thread(target=create)
    t.start()

Java

定义静态私有实例,私有构造函数,公有获取实例方法。去返回类内静态元素。hashCode() 获取对象哈希码

class Singleton {

  private static Singleton obj;

  private void Singleton() {

  }

  public static Singleton getObject() {
    if (obj != null) {
      return obj;
    }
    synchronized (Singleton.class) {
      if (obj == null) {
        try {
          Thread.sleep(3000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }

        obj = new Singleton();
      }
      return obj;
    }
  }

  public static void main(String[] args) {
    for (int i = 0; i <10; i++) {
      Thread  t = new Thread(new Runnable() {
        @Override
        public void run() {
          System.out.println(Singleton.getObject().hashCode());
        }
      });
      t.start();
    }
  }

}