自己理解
单例模式顾名思义,就是在任何时候单例模式的类的有且只能有一个实例,就是单例模式。
自己理解优点
- 减少内存占用
- 提高系统性能
- 实际应用,比如整个系统只需要创建一个实例的情况,或者创建某个实例消耗资源过大... 都可以根据自己的实际应用来制定是否需要用单例模式。
自己思考
知道概念,接下来就是如何创造这个类,这个类和其他类有什么不同。
- 构造方法私有化。因为这个类有且只能有一个实例,所以要保证构造方法不能对外开放。
- 访问对象的方法指向唯一的实例。
- 如何构造这个实例,是在类加载的时候?还是在第一个获取实例对象的时候?
创建方式
1、饿汉式
就是在类加载的过程中创建对象。
实例作为静态变量创建
- 这种构建方式能通过反射的方式来破坏单例模式内部结构。
java
public class Demo {
/**
* 构造方法私有化
*/
private Demo() {
}
/**
* 构造实例 - 类加载过程中
*/
private static Demo demo = new Demo();
/**
* 获取实例方法
* @return
*/
public static Demo getDemo(){
return demo;
}
public void mess(){
System.out.println("hello");
}
}
实例在静态代码块创建
- 这种构建方式能通过反射的方式来破坏单例模式内部结构。
java
public class Demo {
/**
* 构造方法私有化
*/
private Demo() {
}
/**
* 实例变量
*/
private static Demo demo;
/**
* 类加载过程中 创建实例对象
*/
static {
demo = new Demo();
}
/**
* 获取实例方法
* @return
*/
public static Demo getDemo(){
return demo;
}
public void mess(){
System.out.println("hello");
}
}
枚举的方式创建 (*推荐)
- 枚举的方式可以避免反射来破坏内部结构。
java
public enum Demo {
DEMO;
public void mess(){
System.out.println("hello");
}
}
2、懒汉式
就是在使用实例的时候才创建这个实例。
创建方式 - 线程不安全
java
public class Demo {
private static Demo demo;
/**
* 私有构造方法
*/
private Demo(){}
/**
* 线程不安全
* 在第一次使用实例对象的时候创建实例
* @return
*/
public static Demo getDemo(){
if(demo == null){
demo = new Demo();
}
return demo;
}
public void mess(){
System.out.println("hello");
}
}
创建方式 - 线程安全 (* 推荐)
java
public class Demo {
private static Demo demo;
/**
* 私有构造方法
*/
private Demo(){}
/**
* 重量级锁 synchronized
* 在第一次使用实例对象的时候创建实例
* @return
*/
public static synchronized Demo getDemo(){
if(demo == null){
demo = new Demo();
}
return demo;
}
public void mess(){
System.out.println("hello");
}
}
比较两种创建方式
我主张的一般都是根据实际业务需要、服务器内存使用情况和系统开销来确定使用哪种方式,但是一般情况下,我觉得在业务量不大的情况下,无脑饿汉式足够使用了,更为推荐的是饿汉式中的枚举创建,简单、有效、成熟、而且代码量少。