单例模式多种写法
饿汉式
顾名思义 饿汉式 不管你有没有调用获取实例的方法 该实例对象依然会被创建,浪费内存空间。饿汉式又有多种写法
1、 最常见的写法
好处就是用法简单很常见
缺点浪费内存空间。
public class SingletonTest01 {
public static void main(String[] args) {
//测试
SingleTon singleTon = SingleTon.getInstance();
SingleTon singleTon1 = SingleTon.getInstance();
System.out.println(singleTon == singleTon1);
System.out.println(singleTon.hashCode());
System.out.println(singleTon1.hashCode());
}
}
//饿汉式
class SingleTon{
//构造器私有化
private SingleTon(){}
//本类内部创建对象实例
private static final SingleTon instance = new SingleTon();
//对外提供共有的静态方法 返回实力对象
public static SingleTon getInstance(){
return instance;
}
}
2、静态代码块方式
其实跟第一种方式区别不大,类加载时还是会创建实例对象,如果没有使用它导致浪费内存空间。
public class SingletonTest02 {
public static void main(String[] args) {
//测试
SingleTon singleTon = SingleTon.getInstance();
SingleTon singleTon1 = SingleTon.getInstance();
System.out.println(singleTon == singleTon1);
System.out.println(singleTon.hashCode());
System.out.println(singleTon1.hashCode());
}
}
//饿汉式
class SingleTon{
//构造器私有化
private SingleTon(){}
//本类内部创建对象实例
private static SingleTon instance;
static { //在静态代码当中创建单例对象
instance = new SingleTon();
}
//对外提供共有的静态方法 返回实力对象
public static SingleTon getInstance(){
return instance;
}
}
懒汉式
懒汉式顾名思义,当使用的时候再创建这样可以节省内存空间。
1、创建实例对象之前先检查
存在的缺点就是线城是非安全的,如果多个线程一起进入了那么会创建多个对象
//懒汉式 1 线程不安全的
public class SingleTest03 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance == instance1);
System.out.println(instance.hashCode());
System.out.println(instance1.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton(){}
//提供一个静态方法,当时用到该方法的时候才去创建这个实例
//懒汉式
public static Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
2、同步机制
相信很多人都想到了,既然线程不安全那么就加个关键字嘛。
每一次线程都需要等待,那么执行的效率又十分低下了。(不推荐)
//懒汉式 2 线程安全的 但是需要同步效率较低
public class SingleTest04 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance == instance1);
System.out.println(instance.hashCode());
System.out.println(instance1.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton(){}
//提供一个静态方法,当时用到该方法的时候才去创建这个实例
//懒汉式 2 (线程同步 synchronized)
public static synchronized Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
3、线程安全又效率高(推荐使用)
//懒汉式 3 线程安全的 双重检查机制
public class SingleTest05 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
System.out.println(instance == instance1);
System.out.println(instance.hashCode());
System.out.println(instance1.hashCode());
}
}
class Singleton{
//加关键字
private static volatile Singleton instance;
private Singleton(){}
//提供一个静态方法,双重检查机制 解决线程安全 又能解决懒加载问题
//懒汉式 3 推荐
public static Singleton getInstance(){
if (instance == null){
synchronized (Singleton.class){
if (instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}