JAVA学习笔记(三)

2018-05-14  本文已影响24人  郡王丶千夜

前言:

这周忙的不行,没学多少东西,就简单的学习下Java的单例吧。

设计模式之单例

单例模式是最简单也是最常用的设计模式,在学习OC的过程中第一个接触的设计模式就是单例,所以从单例入手来了解Java的一些特性也是极好的。

1.懒汉式单例

public class JMSingleManager {
    private JMSingleManager() {}
    private static JMSingleManager instance = null;
    //类方法
    public static JMSingleManager shareInstance() {
        if (instance == null) {
            instance = new JMSingleManager();
        }
        return instance;
    }
}

1.为了实现在整个软件的生命周期内这个类只能存在唯一一个实例,我们必须把Java默认提供的构造器私有化,这样在外部就不能new一个对象了。
2.置于为什么要用类方法去实现单例,是因为类必须实例化一个类之后才能调用实例方法,总不能为了得到单例每次都要重新new一个对象吧,这样写十分怪异,并且性能也很差。
3.由于类方法只能访问类中的静态成员变量,所以该对象的定义也必须声明为static。

我们发现Java的单例写法和OC中的写法基本一致,但是很容易发现的一个问题就是这种创建方式是线程不安全的,多个线程同时访问可能会实例化多次,所以我们必须加上线程锁,就像在OC中使用dispatch_once一样,但是最常用的还是synchronized这个方法,在Java中也有synchronized,在使用上也和OC非常相像,我们把代码改成下面这样:

public static JMSingleManager shareInstance() {  
    if (instance == null) {    
        synchronized(JMSingleManager.class){
           instance = new JMSingleManager();  
        }
    }    
    return instance;  
}

在这里我们用synchronized修饰JMSingleManager这个类,类的所有对象共用一个锁,synchronized不仅可以用来修饰,还能修饰指定的对象,也可以修饰实例方法类方法,而且也可以修饰一个代码块,比如上述的代码可以改成下面这样:

public static synchronized JMSingleManager shareInstance() {  
     if (instance == null) {    
         instance = new JMSingleManager();  
     }    
     return instance;  
}

这里还有一种写法,需要借助Java的关键字final

final:被final修饰的类无法被继承,被final修饰的方法无法被重写,被final修饰的变量只能被初始化一次,这里我们就要用这个特性,而且被final修饰的变量是天然线程安全的(因为只能初始化一次啊!)

所以单例我们可以这样写:

public class JMSingleManager {    
    private static class LazyHolder {    
       private static final JMSingleManager instance = new JMSingleManager();    
    }    
    private JMSingleManager (){}    
    public static final JMSingleManager shareInstance() {    
       return LazyHolder.instance;    
    }    
}    

2.饿汉式单例

public class JMSingleManager {    
    private JMSingleManager (){}    
    private static JMSingleManager instance = new JMSingleManager(); 
    public static JMSingleManager shareInstance() {    
       return instance;    
    }    
}  

这里主要通过Java的类加载机制来规避线程不安全的风险,也是最简单与最方便的写法。
关于Java的类加载机制个人现在了解的还十分浅薄,以后等了解深一点再来聊聊。

上一篇下一篇

猜你喜欢

热点阅读