概念
许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如某个服务的配置信息,某个系统的打印机。单例模式与静态变量思路很像,其目的是建立一个全局唯一的对象。那么我们为什么不用static去修饰我们需要的对象呢?为什么引入单例模式?原因有两个
(1)static不易拓展
(2)单例模式可以实现在需要的时候创建对象,而static只能在运行时创建。
实现思路
那么我们怎么实现单例模式呢?
我们来回顾,我们是怎么样创建对象的?是new。new方法里会自动找到类的构造方法,(类具有默认的构造方法,可以不显示声明),所以我们首先要限制其他处的代码就无法通过调用该类的构造方法来实例化该类的对象。其次,提供一个能够获取对象的静态方法使外部能够直接通过类名来调用方法得到类的对象。
单例的实现主要是通过以下两个步骤:
(1)将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;
(2)在该类内提供一个获取对象的静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。
代码实现
那么我们应该怎么写呢?我们写两个最简单的:
懒汉式:
package JAVA设计模式.单例模式;
/**
* Author:haozhixin
* Func: 单例模式 懒汉式
* Date: 20190814
*/
public class LazySingleton {
private static LazySingleton singleton;
private LazySingleton(){
}
public static LazySingleton getLazySingleton(){
if(singleton==null){
singleton=new LazySingleton();
}
return singleton;
}
public void gogo(){
System.out.println("12121");
}
}
饿汉式:
package JAVA设计模式.单例模式;
/**
* Author:haozhixin
* Func: 单例模式 饿汉式
* Date: 20190814
*/
public class HungrySingleton {
private static HungrySingleton hungrySingleton;
private HungrySingleton(){
}
public static HungrySingleton getHungrySingleton(){
return hungrySingleton;
}
}
问题分析
懒汉式的代码实现是有问题的,我们考虑下边一种情况,
在对象被创建之前,当两个线程同时进入if判断后,结果new了两次对象,导致线程的不安全。注意:只是在对象被创建之前才会有这个问题!!
那么我们怎么解决呢?
(1)我们可以用synchronized方法修饰提供实例的方法。代码这么写
public static synchronized LazySingleton getLazySingleton(){
if(singleton==null){
singleton=new LazySingleton();
}
return singleton;
}
(2)使用饿汉式设计,保证在使用之前就已经创建。见上述代码。
(3)用双重检查加锁
package JAVA设计模式.单例模式;
/**
* Author:haozhixin
* Func:单例模式优化(双重检查加锁)
* date:20190814
* */
public class LazySingletonCheck {
private volatile static LazySingletonCheck lazySingletonCheck;
private LazySingletonCheck(){
}
public static LazySingletonCheck getLazySingletonCheck(){
if(lazySingletonCheck ==null){
synchronized (LazySingletonCheck.class){
if(lazySingletonCheck==null){
lazySingletonCheck=new LazySingletonCheck();
}
}
}
return lazySingletonCheck;
}
}
总结
以上就是单例模式的设计,希望大家在实际工作中灵活运用,特别要注意线程问题。
下一篇主要介绍单例模式的高效代码实现,欢迎关注 及点赞!
作者:select you from me
来源:优快云
转载请联系作者获得授权并注明出处。