单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。
通常单例模式在Java语言中,有两种构建方式:
- 懒汉方式。指全局的单例实例在第一次被使用时构建。
- 饿汉方式。指全局的单例实例在类装载时构建。
懒汉模式
/**
* 单例模式-懒汉模式或称为饱汉模式
* 用户获取实例的时候才创建这个实例
* 区别:饿汉模式的特点是加载类时比较慢,但是运行时获取对象的速度比较快;线程安全
* 懒汉模式的特点是加载类时比较快,但是运行时获取对象的速度比较慢;线程不安全
*/
public class Singleton2 {
//1.将构造方法私有化,不允许外边直接创建对象
private Singleton2(){
}
//2.创建类的唯一实例,使用private static修饰
private static Singleton2 instance;
//3.提供一个用于获取实例的方法,使用public static修饰
public static Singleton2 getInstance(){
if(instance == null){//如果实例为空就创建这个实例
instance =new Singleton2();
}
return instance;
}
}
饿汉模式
/**
*单例模式Singleton
* 应用场合:有写对象只需要一个就足够了
* 作用:保证整个应用程序中某个实例有且只有一个
* 类型:饿汉模式 类加载时候实例就加载。 形象的形容饥饿,需要快速吃,类一加载的时候实例马上加载
*/
public class Singleton {
//1.将构造方法私有化,不允许外部直接创建对象
private Singleton(){
}
//2.创建类的唯一实例,使用private static修饰
private static Singleton instance =new Singleton();
//3.提供一个用于获取实例的方法,使用public static修饰
public static Singleton getInstance(){
return instance;
}
}
测试类
public class Test {
public static void main(String[] args) {
//饿汉模式
Singleton s1 =Singleton.getInstance();
//懒汉模式
Singleton2 s2=Singleton2.getInstance();
}
}
区别:
- 饿汉模式的特点是加载类时比较慢,但是运行时获取对象的速度比较快;线程安全
- 懒汉模式的特点是加载类时比较快,但是运行时获取对象的速度比较慢;线程不安全
双层判断加同步锁 保证懒汉模式线程安全
public class TestDoubleSingleton {
private static TestDoubleSingleton testDoubleSingleton;
private TestDoubleSingleton(){
}
private static TestDoubleSingleton getSingleton(){
if(testDoubleSingleton == null){
synchronized (TestDoubleSingleton.class){
if(testDoubleSingleton == null){
return new TestDoubleSingleton();
}
}
}
return testDoubleSingleton;
}
public static void main(String[] args) {
TestDoubleSingleton.getSingleton();
}
}
枚举特性 单例模式
public enum TestEnumSingleton {
SIN;
public void method(){
}
}
单例的枚举实现在《Effective Java》中有提到,因为其功能完整、使用简洁、无偿地提供了序列化机制、在面对复杂的序列化或者反射攻击时仍然可以绝对防止多次实例化等优点,单元素的枚举类型被作者认为是实现Singleton的最佳方法。
属性都是static类型的,因为static类型的属性会在类被加载之后被初始化,当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的。所以,创建一个enum类型是线程安全的。