文章目录
参考文章
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(){
}
}
版权声明:本文为qq_43590771原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。