一:单例模式
- 只能有一个实例
- 必须自己创建自己的唯一实例
- 必须给所有其他对象提供这一实例
- 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点
- 主要解决:一个全局使用的类频繁地创建与销毁
- 何时使用:当想控制实例数目,节省系统资源的时候
- 关键代码:构造函数是私有的
//创建一个singleton 类
public class SingleObject {
//创建SingleObject的对象
private static SingleObject instance = new SingleObject();
//让构造函数为private, 这样该类就不会被实例化
private SingleObject(){}
//获取唯一可用的对象
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
**
* 从singleton 类获取唯一的对象
*/
public class SingletonPatternDemo {
public static void main(String[] args){
/**
* 不合法的构造函数
* 编译时错误:构造函数SingleObject 是不可见的
* SingleObject object = new SingleObject();
*/
//获取唯一可用的对象
SingleObject object = SingleObject.getInstance();
//显示消息
object.showMessage();
}
}
输出结果:Hello World!
二:实现方式
/**
* 单例模式:懒汉式,线程不安全
* 是否 Lazy 初始化:是
* 是否多线程安全:否
* 实现难度:易
* 描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
* 这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
*/
public class SingletonLazy {
private static SingletonLazy instance;
private SingletonLazy(){}
private static SingletonLazy getInstance(){
if(instance == null){
instance = new SingletonLazy();
}
return instance;
}
}
/**
* 单例模式:懒汉式,线程安全
* 是否 Lazy 初始化:是
* 是否多线程安全:是
* 实现难度:易
* 描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
* 优点:第一次调用才初始化,避免内存浪费。
* 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
* getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)
*/
public class SingletonLazy2 {
private static SingletonLazy2 instance;
private SingletonLazy2(){}
public static synchronized SingletonLazy2 getInstance(){
if(instance == null){
instance = new SingletonLazy2();
}
return instance;
}
}