单例模式:保证整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式
在Java中,单例模式有几种实现方式:
- 私有构造器
- 静态内部类
1. 私有构造器
饿汉式:在类刚被加载的时候,马上就创建对象,生怕抢不到吃的
public class SingleObject {
//在类被加载时,就创建对象
private static SingleObject instance = new SingleObject(0);
//私有化构造器,防止外部创建对象
private SingleObject(int i){
System.out.println("我是一个单例"+i);
}
//提供外界获取唯一对象的方法
public static SingleObject getSingletonInstance(){
return instance;
}饿汉式虽好,但是总感觉还是有点问题,因为它在类刚被加载的时候,就各种创建对象,如果我暂时还不需要的话,这样其实是会造成资源的浪费的,所以还不完美,怎么来解决这个问题呢;大家应该经常听到懒加载这个词,它的意思就是所有的事情我都不着急,只有你需要我的时候我才出现,这个模式就是懒汉式。
懒汉式:一开始比较懒,不去创建对象,等到程序需要我的时候,实在没法再拖了,就只能创建对象了
public class LazyInitializedSingleton {
//需要对象时候再去创建
private static LazyInitializedSingleton instance;
//私有化构造器
private LazyInitializedSingleton(){}
/**对外暴露的获取单例对象的方法
*存在多线程并发不安全问题,可以通过加锁synchronized关键字 锁会影响性能
*/
public static synchronized LazyInitializedSingleton getSingletonInstance(){
//判断是否已经创建了对象,没有就创建,有就直接返回
if(instance == null){
instance = new LazyInitializedSingleton();
}
return instance;
}
}加锁后,线程安全问题解决了,但是由于加锁又带来了性能的问题;真是一波未平一波又起啊,性能问题在也是极其重要的问题,这里我们就要换一个思路了
2. 静态内部类
用静态内部类的方式来实现单例模式
public class InnerHelperSingleton {
private InnerHelperSingleton(){}
//静态内部类,只在getInstance方法内使用
private static class SingletonHelper{
private static final InnerHelperSingleton INSTANCE = new InnerHelperSingleton();
}
//返回接口
public static InnerHelperSingleton getSingletonInstance(){
return SingletonHelper.INSTANCE;
}
}这种方式跟饿汉式方式采用的机制类似,但又有不同;两者都是采用了类加载的机制来保证初始化实例时只有一个线程。
饿汉式和静态内部类方法的不同点:
饿汉式是只要Singleton类被加载就会实例化,没有懒加载
静态内部类方式结合了“饿汉”和“懒汉”二者的优点,是在需要实例化时,调用getInstance方法,才会加载SingletonHolder类,实例化Singleton。
由于类的静态属性只会在第一次加载类的时候初始化,所以在这里我们也保证了线程的安全性,所以通过这种静态内部类的方式解决了资源浪费和性能的问题。
静态资源内部类的方式是比较推荐的一种写法。



京公网安备 11010502036488号