当前位置: 主页 > JAVA语言

单例模式 java-A4纸画出单例模式的UML图

发布时间:2023-06-20 22:09   浏览次数:次   作者:佚名

拿出一张A4纸画出单例模式的UML图(面试时如果被问到设计模式相关问题,能先画出UML图肯定是加分项):

java单例模式例子_单例模式 java_java单例模式应用场景

单例模式UML图

估计很多小伙伴都忘记怎么读UML图了吧?这里详细解释下:

单例模式具体实现细节,看英文解释会更直观:

1.The implementation involves a static member in the "Singleton" class,

静态成员变量instance

2.a private constructor

私有构造函数

3.a static public method that returns a reference to the static member.

public static修饰的返回一个实例对象的方法

一段简单的代码实现:

public final class Singleton {

//类一加载时实例就被创建

private static final Singleton instance = new Singleton();

单例模式 java_java单例模式例子_java单例模式应用场景

private Singleton() {

}

public static Singleton getInstance() {

return instance;

}

}

当然如果面试时仅仅写出上面的代码是远远不够的,面试官不会轻易让我们过关的,这只是刚刚热身,更深入的问题还在后面:

1.你知道懒加载吗?是怎么用在单例创建上的?有什么优势?

如果某个实例的创建(比如数据库连接池的创建)需要消耗很多系统资源,就需要引入懒加载机制。即上面的代码在类加载时就创建好了单例模式 java,如果在程序中始终没用到这个实例就会浪费很多系统资源。

为避免这种情况,就引入了懒加载机制,即在使用这个实例的时候才创建它。

引入懒加载后的单例实现代码如下(这就是我们常听到的“懒汉式”单例):

public class Singleton{

private static Singleton instance = null;

private Singleton(){

单例模式 java_java单例模式应用场景_java单例模式例子

}

public static Singleton getInstance(){

if (instance == null)

//实例在调用getInstance()函数的时候才会创建

instance = new Singleton(); //1. A线程执行

return instance; //2.B线程执行

}

}

2.这个例子你考虑到线程安全了吗?什么是线程同步?什么是双重检查锁定?怎么用在单例上?

的确当引入多线程时,以上代码不是线程安全的:假设A线程执行代码1的同时,B线程执行代码2。此时,线程A可能会看到instance引用的对象还没有完成初始化。

通过Java语言的关键字synchronized实现线程同步,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。因此通过对函数getInstance()做同步处理来实现线程安全的初始化:

class Singleton

{

private static Singleton instance;

private Singleton()

单例模式 java_java单例模式应用场景_java单例模式例子

{

...

}

public static synchronized Singleton getInstance()

{

if (instance == null)

instance = new Singleton();

return instance;

}

...

public void doSomething()

{

...

}

}

单例模式 java_java单例模式应用场景_java单例模式例子

上面的代码是线程安全的一种实现,但是如果考虑到性能单例模式 java,synchronization是非常消耗资源的,一次只能有一个线程调用getInstance()方法,而getInstance方法在对象实例化之后无需再阻塞访问。即如果对象已经创建完成,只需要return 这个对象就OK了,不需要用syncronized同步。

因此进一步优化:先在非synchronized块检查object是否为null,是就直接return object,否则进入syncronized同步块创建object,这就成为双重锁机制(double locking mechanism).

代码实现如下:

//Lazy instantiation using double locking mechanism.

class Singleton

{

private static Singleton instance;

private Singleton()

{

System.out.println("Singleton(): Initializing Instance");

}

public static Singleton getInstance()

{

if (instance == null) //1.第一次检查

{

java单例模式应用场景_单例模式 java_java单例模式例子

synchronized(Singleton.class)//2.加锁

{

if (instance == null) //3.第2次检查

{

System.out.println("getInstance(): First time getInstance was invoked!");

instance = new Singleton(); //4.实例化对象

}

}

}

return instance;

}

public void doSomething()

{

System.out.println("doSomething(): Singleton does something!");

}

}