单例模式是Java中常见的设计模式之一,简单来说就是只希望类中产生唯一的实例化对象。
(饿汉式单例、懒汉式单例设计代码见文末)
实现方式:
- 将被实现的类的构造方法设计成private
- 添加此类引用的静态成员变量,并为其实例化
- 在被实现的类中提供公共的Create Instance函数,返回实例化的此类,就是2中的静态成员变量
适用场景:
- 需要频繁实例化然后销毁的对象
- 创建对象时耗时过多或者耗资源过多,但又经常用到的对象
- 有状态的工具类对象
- 频繁访问数据库或文件的对象
场景举例:
- 每台计算机有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机;
- Windows的TaskManager(任务管理器),不能打开两个windows task manager;
- Windows的Recycle Bin(回收站),在整个系统运行过程中,回收站一直维护着仅有的一个实例;
- 网站的计数器,一般也是采用单例模式实现,否则难以同步;
优点:保证一个类仅有一个实例,并提供一个他的全局访问点,避免一个全局使用的类频繁的创建和销毁,节省系统资源,提高程序效率
缺点:常见的内存泄漏情况中就有单例造成的内存泄漏,因为单例的静态特性使得其生命周期和应用的生命周期一样长,如果一个对象已经不再需要使用了,而单例对象还持有该对象的引用,就会使得该对象不能被正常回收,从而导致了内存泄漏。
饿汉式单例:
特点:构造方法私有化,外部无法产生新的实例化对象,只能通过static方法取得实例化对象
class Singleton {
private final static Singleton instance = new Singleton();
//在类的内部可以访问私有结构,所以可以在类的内部产生实例化对象
private Singleton() { //private声明构造
}
public static Singleton getInstance() {
return instance;
}
public void print() {
System.out.println("hello");
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton singleton = null;//声明对象
singleton = Singleton.getInstance();
singleton.print();
}
}
懒汉式单例
特点:当第一次使用Singleton对象时才会产生为其实例化的操作
缺点:懒汉式存在多线程安全问题
class Singleton {
private final Singleton instance;
private Singleton() {//private声明构造
}
public static Singleton getInstance() {
if (instance == null) { //表示此时还没有被实例化
instance = new Singleton();
}
return instance;
}
public void print() {
System.out.println("hello");
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton singleton = null;//声明对象
singleton = Singleton.getInstance();
singleton.print();
}
}