首先说一下·为什么要学习使用单例。
- 某些类呢,创建比较频繁,所以尤其是对于一些大型的对象,这是一笔大的系统开销。
- 省去了new这个操作符,降低了对系统内存的使用频率,减轻了GC压力。
-
懒汉式
顾名思义,懒汉式只有在调用的时候才会去创建静态对象 。
private static SingletonLh singletonLh = null;
//创建一个私有化无参构造,防止实例化
private SingletonLh(){
}
public static SingletonLh getSingletonLh(){
//对象第一次被调用时为空,此时就会创建一个对象。
if(singletonLh == null){
return singletonLh = new SingletonLh();
}
return singletonLh;
}
-
饿汉式
饿汉式是在项目启动加载类的时候就创建了静态对象,所以线程是安全的。
//饿汉式直接创建对象
private static SingletonEh singletonEh = new SingletonEh();
private String name;
public void SingletonEh(){
}
//在调用的时候就可以直接返回
public static SingletonEh getSingletonEh(){
return singletonEh;
}
public static void main(String[] args) {
//这里new两个对象调用方法,==判断的不仅是值,还包括内存地址。
//所以结果为true,则单例实现
/* SingletonLh singletonLh1 = SingletonLh.getSingletonLh();
SingletonLh singletonLh2 = SingletonLh.getSingletonLh();
System.out.println(singletonLh1 == singletonLh2);*/
SingletonEh singletonEh1 = SingletonEh.getSingletonEh();
SingletonEh singletonEh2 = SingletonEh.getSingletonEh();
System.out.println(singletonEh2 == singletonEh1);
}
他们两个最明显的区别就是,因为饿汉式在类加载时就创建,所以说如果对象大的时候,会占用jvm资源,影响效率。懒汉式是延迟加载。从线程上的安全上来考虑,饿汉式还是更推荐些。当然你也可以为懒汉式配置双重判定锁。
public static SingletonLh getSingletonLh(){
//第一个为空校验,是为了节约资源
if(singletonLh == null){
//同步锁可以限制多线程,如果第一次为空进来了多个空值
//在第一次通过锁new对象之后,其他的空值就被第二个if挡住。
synchronized (SingletonLh.class){
if (singletonLh == null){
return singletonLh = new SingletonLh();
}
}
}
return singletonLh;
}
感谢您的阅读,Life is good!