单例设计模式
简述:
单例模式(Singleton Pattern)是java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式设计到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象呗创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意单例设计模式的特点:
- 构造函数私有化
- 提供一个共有的公外部调用的静态方法
- 实例对象私有化
1、单例设计模式的种类
单例设计模式大致可分为两种,懒汉式和饿汉式。二者各有优缺点:
类别 | 优点 | 缺点 |
---|---|---|
懒汉式 | 相比之下节省内存,在使用到的时候才会进行实例化。 | 在多线程下创建不安全。 |
饿汉式 | 多线程情况下是线程安全的,因为在类加载之后就实例化了。 | 相比于懒汉式,这种行为占用内存,如果存在大量的懒汉式,其内部数据结构相对复杂,并且使用不到该类的时候就纯属于资源浪费。 |
1.、懒汉式
public class SingletonPattern {
private static SingletonPattern INS = null;
private SingletonPattern(){}
public static SingletonPattern getIns() {
if (INS == null) {
INS = new SingletonPattern();
}
return INS;
}
}
供外部使用:
public class Test{
public static void main(String[] args) {
SingletonPattern.getIns(); // todo
}
}
上述这种方式在多线程情况下会存在线程1先调用getIns方法,线程执行到if语句的时候,此时线程2也执行到if语句,线程1执行赋值语句,线程2紧跟着执行赋值语句,此时线程1的实例对象会被线程2的实例对象覆盖。
2、饿汉式
public class SingletonPattern {
private static final SingletonPattern INS = new SingletonPattern();
private SingletonPattern(){}
public static SingletonPattern getIns() {
return INS;
}
}
供外部使用:
public class Test{
public static void main(String[] args) {
SingletonPattern.getIns(); // todo
}
}
上述饿汉式在类加载之后就进行实例化了,一因此该实例不存在线程抢占实例化问题。
3、懒汉式线程安全-锁
上述懒汉是中存在线程安全问题,未解决这一类线程引起的问题,可以通过加锁的方式。
方法加关键字synchronized
public class SingletonPattern {
private static SingletonPattern INS = null;
private SingletonPattern(){}
public static synchronized SingletonPattern getIns() {
if (INS == null) {
INS = new SingletonPattern();
}
return INS;
}
}
锁类:
public class SingletonPattern {
private static SingletonPattern INS = null;
private SingletonPattern(){}
public static SingletonPattern getIns() {
if (INS == null) {
synchronized(SingletonPattern.class) {
if (INS == null) {
INS = new SingletonPattern();
}
}
}
return INS;
}
}