在实际的开发中,绝大部分的服务性质的类都会设计成单例模式
所谓的单例模式,就是类只有(只产生)一个对象,外部要使用该类的对象,通过调用一个类方法实现。
比如说,我们打印机连接电脑,无论多少的打印机与电脑相连,实现操作控制的只能是一台电脑。如果一台打印机连接两台电脑,这两台电脑都对打印机作出指示,就会打印出错。
特点:
1.单例类只能有一个实例。
2.单例类必须自己创建自己的唯一实例。
3.单例类必须给所有其他对象提供这实例
一,饿汉式实例在初始化的时候已经创建好了,好处是没有线程安全问题,但是浪费内容空间。
public class Singleton{
private static Singleton instance = new Singleton();
private Singleton(){
}
private static Singleton getInstance(){
return instance;
}
}
二,懒汉式用的时候才创建实例,会产生线程的不安全问题。
public class SingletonDemo2{
private static SingletonDemo2 instance = null;
private SingletonDemo2(){
}
public static SingletonDemo2 getInstance(){
if(instance == null) {
instance = new SingletonDemo2();
}
return instance;
}
}
三,静态内部类单例模式只有在访问 getInstance() 方法来获取实例的时候才会加载内部类,达到延迟加载的效果,且是线程安全的
public class Singleton{
private Singleton(){
}
private static class InnerClass{
private static final Singleton SINGLETON = new Singleton();
}
public static final Singleton getInstance() {
return InnerClass.SINGLETON;
}
}
四,枚举线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用
public enum Singleton{
public void operation() {
System.out.println(".....");
}
}
五,双重检查加锁双重检查加锁不像懒汉式那样一访问就加锁,而是先检查当前实例是否已经创建,如果未创建,再进行同步(加锁)来创建实例,这样只有第一次使用时才会进行同步,又能达到延迟加载
public class Singleton{
private volatile static Singleton singleton;
private Singleton(){
}
public static Singleton getInstance() {
if(singleton == null) {
}
synchronized (Singleton.class) {
singleton = new Singleton();
}
return singleton;
}
}
总结: 如果不需要延迟加载单例,可以使用枚举或者饿汉式,相对于枚举性好于饿汉式。 如果需要延时加载,可以使用静态内部类或者懒汉式。