1.单例模式介绍
单例模式(Singleton Pattern)是java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 注意:
单例类只能有一个实例 单例类必须自己创建自己的唯一实例 单例类必须给所有其他对象提供这一实例
2.为什么要使用单例模式?
public class Printer {
private static Printer printer = null;
private Printer ( ) {
}
public static synchronized Printer getInstance ( ) {
if ( printer == null) {
printer = new Printer ( ) ;
}
return printer;
}
}
上面这段代码,是单例模式中的懒汉方式实现,首先向外提供了一个可被访问的实例化的对象,如果没有此对象,那么创建一个返回,并且在遇到多线程并发访问时,加上关键字synchronized,上锁,让没有持有该对象的类处于等待状态,当前持有该printer的线程任务结束之后,处于等待中的线程才能逐个去持有该实例,去操作其方法。这样的一个过程在编程中称为单例模式。 我们可以想想,如果在系统中不使用单例模式的化,在遇到多线程访问的时候,printer就会给要请求的类分别在内存中new出一个printer对象,让这些请求的类去做print方法,这样大量占有内存,就会导致系统运行变慢,所以这个时候,单例模式就出现了。 **意图:**保证一个类仅有一个实例,并提供一个访问它的全局访问点 **主要解决:**一个全局使用的类频繁的创建与销毁 **何时使用:**当你想控制实例的数目,节省系统的资源的时候 **关键代码:**构造函数私有化 应用实例:
一个党只能有一个书记 windows是多进程多线程的,在操作一个文件的时候,就不可避免的出现多个进程或线程操作一个文件的现象,所以所有的文件处理就必须通过唯一的实例来进行 一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。 优点:
在内存中只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例 避免对资源的多重占用 缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化
3.单例模式的实现
1.懒汉写法
public class Singleton {
private static Singleton singleton;
private Singleton ( ) {
}
public static Singleton getInstance ( ) {
if ( singleton == null) {
singleton = new Singleton ( ) ;
}
return singleton;
}
}
public class Singleton {
private static Singleton instance;
private Singleton ( ) { }
public static synchronized Singleton getInstance ( ) {
if ( instance == null) {
instance = new Singleton ( ) ;
}
return instance;
}
}
2.饿汉写法
public class Singleton {
private static Singleton instance = new Singleton ( ) ;
private Singleton ( ) { }
public static Singleton getInstance ( ) {
return instance;
}
}
3. 双重锁写法(是懒汉模式的升级版) 进行双重判断,当已经创建过实例对象后就无需加锁,提高效率,也是一种推荐的使用方式
public class Single {
private Single ( ) {
}
private volatile static Single single;
public static Single getInstance ( ) {
if ( single == null) {
synchronized ( Single. class ) {
if ( single == null) {
single = new Single ( ) ;
}
}
}
return single;
}
}
4.静态内部类写法
public class Singleton {
privite static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton ( ) ;
}
private Singleton ( ) { }
public static final Singleton getInstance ( ) {
return SingletonHolder. INSTANCE;
}
}
5. 枚举写法(是effective java中的推荐写法,它不仅可以避免多线程的同步问题,还可以防止反序列化重新创建新的对象)
public enum Singleton{
INSTANCE;
public void whateverMethod ( ) {
}
}