饿汉式与懒汉式的代码实现及比较
饿汉式的代码实现
1. 步骤
(1) 创建类中私有构造;
(2) 创建该类型的私有静态实例;
(3) 创建公有静态方法返回静态实例对象。
2. 饿汉式代码
package com.study.singleton;
//饿汉式:创建对象实例的时候直接初始化 空间换时间
public class SingletonOne {
//1、创建类中私有构造
private SingletonOne(){
}
//2、创建该类型的私有静态实例
private static SingletonOne instance=new SingletonOne();
//3、创建公有静态方法返回静态实例对象
public static SingletonOne getInstance(){
return instance;
}
}
3. 测试
package com.study.test;
import com.study.singleton.SingletonOne;
import com.study.singleton.SingletonTwo;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
SingletonOne one =SingletonOne.getInstance();
SingletonOne two=SingletonOne.getInstance();
System.out.println(one);
System.out.println(two);
}
}
运行结果:
com.study.singleton.SingletonOne@15db9742
com.study.singleton.SingletonOne@15db9742
4. 饿汉式小结
饿汉式的本质是空间换时间,在类进行加载的时候,静态的实例对象就完成了操作,即不论用于不用,已经建出来了,放在那里了,什么时候想要,什么时候拿即可。
懒汉式的代码实现
1. 步骤
(1) 创建私有构造方法;
(2) 创建静态的该类实例对象;
(3) 创建开放的静态方法提供实例对象。
2. 懒汉式代码
package com.study.singleton;
//懒汉式:类内实例对象创建时并不直接初始化,直到第一次调用get方法时,才完成初始化操作
//时间换空间
public class SingletonTwo {
//1、创建私有构造方法
private SingletonTwo(){
}
//2、创建静态的该类实例对象
private static SingletonTwo instance=null;
//3、创建开放的静态方法提供实例对象
public static SingletonTwo getInstance(){
if(instance==null)
instance=new SingletonTwo();
return instance;
}
}
3. 测试
package com.study.test;
import com.study.singleton.SingletonOne;
import com.study.singleton.SingletonTwo;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
SingletonTwo one1 =SingletonTwo.getInstance();
SingletonTwo two1=SingletonTwo.getInstance();
System.out.println(one1);
System.out.println(two1);
}
}
运行结果:
com.study.singleton.SingletonTwo@6d06d69c
com.study.singleton.SingletonTwo@6d06d69c
4. 懒汉式小结
懒汉式的本质是时间换空间,在创建实例时,类加载时,并不会真正开辟对象的空间,只有当我们真正使用的时候,才会提供检测来去判断对象是否已经实例化,此时会耗费时间,因此懒汉式的本质是时间换空间。如果这个实例一直都没有使用,那么这个空间也不会被开辟。
饿汉式与懒汉式的比较
1. 特点比较
(1) 饿汉式:在类加载时就创建实例,以空间换时间;
(2) 懒汉式:第一次使用时进行实例化,以时间换空间。
2. 线程安全性对比
(1) 饿汉式线程安全。饿汉式因为在类加载时就已经进行了对象的实例化创建,因此即便多线程并发操作,访问的实例对象也是唯一的,因此饿汉式线程安全;
(2) 懒汉式存在线程风险。懒汉式是在第一次使用时才会进行实例化,当多个线程并发操作时,由于时间边的切换,则可能倒置风险,因此懒汉式存在线程风险。
(3) 懒汉式风险解决方法:
a. 同步锁;
b. 双重校验锁;
c. 静态内部类;
d. 枚举。