单例模式
先了解什么是单例模式:
Java 中一般认为有 23 种设计模式,单例模式就是其中一种,也加单子模式。
这个模式讲究的是,应用这个模式时,单例对象的类必须保证只有一个实例存在。整个系统只需要拥有一个全局对象,这样有利于我们协调系统整体的行为。一般是整个服务器共享的资源,作为单例对象。比如我们程序开发的日志、缓存、线程池都是被设计成单例模式。
单例模式又分为饿汉式和懒汉式。
思想最重要
我们先谈谈单例模式的设计思想,毕竟设计模式我们主要学习其思想
单例模式讲究的是应用中只要有一个对象就行了,那么我们怎么保证在应用中只有一个对象呢?
1.不允许其他程序去new对象
因为new就是开辟新的内存空间,如果可以new的话 ,那么每次new都产生一个对象,这么就保证不了对象的唯一性
2.在该类中创建对象
因为不允许其他程序创建对象,所以只能在本类中new出来
3.对外提供一个可以获取该对象的方法
对象是本类中创建的,所以需要提供一个外面可以获取对象的方法
我们简单的用代码描述一下:
1.私有化类的构造函数
2.在本类中new一个对象
3.定义公有方法,提供给外界获取对象
接下出看看代码怎么写
饿汉式
饿汉式:一开始就已经先创建好单例实例
public class Singleton {
private static Singleton instance=new Singleton();
private Singleton(){};
public static Singleton getInstance(){
return instance;
}
}
优点:
1.线程安全
2..在类加载的同时已经创建好一个静态对象,调用时反应速度快
缺点:
资源效率不高,容易导致内存浪费,可能getInstance永远不会执行到,但执行该类的其他静态方法或者加载了该类的(classforName),那么这个实例仍然初始化
懒汉式
懒汉式:用的时候才去创建单例实例
public class Singleton {
private static Singleton instance=null;
private Singleton() {};
public static Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
这种写法最大的问题就是线程不安全,那么我们换一种线程安全的写法
public class Singleton {
private static Singleton instance=null;
private Singleton() {};
public static synchronized Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
我们发现加了synchronized,同步方法,但是又出问题了,同步方法效率太低了
后来就出现了一种最好的写法,双重校检锁,比较推荐的一种方式
public class Singleton {
private static Singleton instance=null;
private Singleton() {};
public static Singleton getInstance(){
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
这种写法保证了延迟加载和线程安全。