单例设计模式
1. 什么是单例设计模式:
保证一个类在项目中只有一个实例,并提供访问他的方法。
2. 为什么要用单例设计模式:
对于一些类来说,只有一个实例很重要,如一个会计系统只能专用于一个公司。
3. 单例设计模式适用于什么地方:
------当类只能有一个实例而且客户可以从一个众所周知的访问点访问他时。
------这个唯一实例时通过子类化科扩展的,并且客户端应该无需更改代码就能使用一个扩展实例时。
------需要频繁的创建和销毁对象的时候。
单例设计模式的设计思路:
- 为了防止被外界直接new出,需要重写单例类的空构造方法,并把这个方法私有化。
- 类的内部创建对象。
- 提供一个对外的接口,使需要的地方能通过这个接口获取。
以下使单例模式8种实现案例:
1. 饿汉式实现:
class singletonFirst {
//1、提供私有空构造方法,使外界无法new出
private singletonFirst() { };
//2、在内部实例被单例的类
private final static singletonFirst instance = new singletonFirst();
//3、对外提供访问接口
public static singletonFirst getInstance() {
return instance;
}
}
优势:
- 写法较为简单,类加载时完成实例化,避免了线程同步问题。
劣势:
- 类装载时就完成实例化,可能出现从始至终都没用过这个类的情况,而却创造了这个类的实例,对内存资源造成浪费。
推荐等级:可用,但会造成资源浪费
2、饿汉式静态代码块实现:
class SingletonSecond{
//1、提供私有空构造方法,使外界无法new出
private SingletonSecond() { };
//2、在内部实例被单例的类
private final static SingletonSecond instance;
static {
instance = new SingletonSecond();
}
//3、对外提供访问接口
public static SingletonSecond getInstance() {
return instance;
}
}
优点与缺点:
与上一个方法类似,只是将类实例化放到静态代码块中,优缺点和上面相同
推荐等级:可用,但会造成资源浪费
3、懒汉式实现(线程不安全):
class SingletonThird{
private SingletonThird(){};
private static SingletonThird singletonThird;
public static SingletonThird getInstance(){
if(singletonThird==null){
singletonThird = new SingletonThird();
}
return singletonThird;
}
}
优点:
- 有懒加载效果,但只能用于单线程。
缺点:
- 在多线程下,如果一个线程进入if判断语句,另一个线程也进入该语句,则可能造成多个实例。
推荐:实际开发中,不要使用这种方式
4、懒汉式实现(线程安全):
class SingletonFourth{
private SingletonFourth(){};
private static SingletonFourth singletonFourth;
public synchronized static SingletonFourth getInstance(){
if(singletonFourth==null){
singletonFourth = new SingletonFourth();
}
return singletonFourth;
}
}
优点:
- 实现了懒加载及线程安全
缺点:
- 效率太低,调用方法要等待锁的释放。
推荐:实际开发中,不推荐使用这种方式
5、懒汉式实现(线程安全,同步代码块):
class SingletonFive{
private SingletonFive(){};
private static SingletonFive singletonFive;
public static SingletonFive getInstance(){
if(singletonFive==null){
synchronized (SingletonFive.class){
singletonFive = new SingletonFive();
}
}
return singletonFive;
}
}
优点:
- 有同步代码块,也能有较快的解决速率。
缺点:
- 假如有2个线程同时进入if语句,则会创建不同的对象。
推荐:实际开发中,不能使用这种方式
6、双重检索:
class SingletonSix{
private SingletonSix(){};
private static SingletonSix singletonSix;
public static SingletonSix getInstance(){
if(singletonSix==null){
synchronized (SingletonSix.class){
if(singletonSix==null) {
singletonSix = new SingletonSix();
}
}
}
return singletonSix;
}
}
优点:
- 既能解决线程同步问题,又能有较快的效率,也能实现懒加载。
缺点:
- 无。
推荐:实际开发中,推荐使用这种方式
7、静态内部类实现:
class SingletonSeven{
private SingletonSeven(){};
private static class SingeltonInstance{
private static final SingletonSeven instance = new SingletonSeven();
}
public static SingletonSeven getInstance(){
return SingeltonInstance.instance;
}
}
优点:
- 采用类加载机制保证初始化实例只有一个进程。
- 静态内部类在单例类实例化时不会立即实例化,而是需要实例时调用getInstance方法装载内部类,完成单例类实例。
- 避免了线程不安全,利用静态内部类特点实现延迟加载,效率高。
缺点:
- 无。
推荐:实际开发中,推荐使用这种方式
8、枚举实现:
public class SingletonTestEight {
public static void main(String[] args) {
Singleton singleton = Singleton.INSTANCE;
singleton.say();
}
}
enum Singleton{
INSTANCE;
public void say(){
}
}
优点:
- 借助JDK1.5中的枚举来实现单例模式,能避免多线程安全问题,还能防止序列化重新创建新的对象。
推荐:实际开发中,推荐使用这种方式