3.10单例,前端

102 阅读2分钟

1.手写单例

饿汉 线程安全,但不是懒加载

懒加载:得保证线程安全。一般用双检查锁+volatile

public class Singleton{
    /**
     * 下面属于懒汉非线程安全的方式。即按需加载
     * 加上synchronized就是线程安全了,但是每次判断都需要同步,性能不好
     * 使用饿汉加载
     */
//        private Singleton(){
//        //私有构造方法,禁止别人从这里创建类
//    }
//    //static修饰变量属于类,只有一份
//    private static Singleton singleton;
//    public static synchronized Singleton getInstance(){
//        if (singleton == null){
//            singleton = new Singleton();
//        }
//        return singleton;
//    }

    /**
     *饿汉加载,在类加载把对象加载好,后面就不会再进行类加载了,就不会有线程安全问题
     */

//    private Singleton(){
//        //禁止使用构造方法
//    }
//    private static Singleton singleton;
//    public static Singleton getInstance(){
//        if (singleton == null){
//            singleton = new Singleton();
//        }
//        return singleton;
//    }

    /**
     * 又能懒加载,又能线程安全,且高性能。我们只要在构建对象的时候同步
     * 在使用时不用管就行.
     * 如果实例对象还没构建,加锁。实例被创建之后,以后都不能创建了
     */
    private Singleton(){

    }
//    private static Singleton singleton;
//    public static Singleton getInstance(){
//        if (singleton == null){
//            //这里也会有问题,如果多个线程执行过了if,a线程一旦创建完对象,B线程立马有创建
//            那么还是会导致多次创建
//            synchronized (Singleton.class){
//                singleton = new Singleton();
//            }
//        }
//        return singleton;
//    }

    //解决上面的问题,用双检锁,进行两次判空
//    public static Singleton getInstance(){
//        if (singleton == null){
//            synchronized (Singleton.class){
//                if (singleton == null){
//                    //但是这里可能出现jvm为了优化的指令重排
//                    singleton = new Singleton();
//                }
//            }
//        }
//        return singleton;
//    }

    /**
     * 最终,双检加volatile
     * uniqueInstance 采用 volatile 关键字修饰也是很有必要的。
     * uniqueInstance = new Singleton(); 这段代码其实是分为三步执行。
     * 1.分配内存空间
     * 2.初始化对象
     * 3.将 uniqueInstance指向分配的内存地址
     * 但是由于 JVM 具有指令重排的特性,有可能执行顺序变为了 1>3>2,这在单线程情况下自然是没有问题。
     * 但如果是多线程下,有可能获得是一个还没有被初始化的实例(一个空内存),以致于程序出错。
     * 使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行。
     */
    private volatile static Singleton singleton;
    public static Singleton getInstance(){
        if (singleton == null){
            synchronized (Singleton.class){
                if (singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

静态内部类实现

当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 getUniqueInstance() 方法从而触发 SingletonHolder.INSTANCE 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例。

这种方式不仅具有延迟初始化的好处,而且由虚拟机提供了对线程安全的支持。

public class Singleton {

    private Singleton() {
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getUniqueInstance() {
        return SingletonHolder.INSTANCE;
    }
}

2.jquery

$(div).attr(id)

  1. /返回元素指定属性值

  2. var txt1_val=$("#txt1").attr("value");

  3. //通过元素的DOM属性名更改DOM属性值

  4. $("#txt1").attr({ value : "txt1_value" , className : "txt1_class" });

  5. //通过指定元素属性改变元素属性值

  6. $("#txt1").attr("class","txt1_class2");