单例模式:
单例模式是任何适合都只能有一个实例。且该类需自行创建这个实例,并对其他的类提供调用这一实例的方法。是java中常用的设计模式。
单例模式的特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
饿汉模式(HungrySingLeton)
实例在初始化的时候就要创建好,不管你有没有用到
优点:a.线程安全;
b.在类加载(ClassLoader)的同时已经创建好一个静态对象,调用时反应速度快;
缺点:对象提前创建,所以会占据一定的内存,内存占用大 以空间换时间;
package com.poject.pj.designModel.singModel;
/**
* 单例模式
* 1.饿汉模式(HungrySingLeton)
*
*/
public class HungrySingLeton {
private HungrySingLeton(){};
//饿汉模式
private static final HungrySingLeton hungrySingLeton = new HungrySingLeton();
public static HungrySingLeton getInstance(){
return hungrySingLeton;
}
}
懒汉模式(LazySingLeton)
懒汉模式(线程安全)
对getInstance()方法添加synchronized关键字
由于加载一个类时,其内部类不会同时被加载。一个类被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生。因此使用静态内部类实现的单例模式是懒加载的且线程安全。
/**
* 单例模式
* 2.懒汉模式(LazySingLeton)
*/
public class LazySingLeton {
private static LazySingLeton lazySingLeton;
/**
* 采用静态内部类实现的代码也是懒加载的,
* 1.只有第一次使用这个单例的实例的时候才加载;
* 2.同时不会有线程安全问题
*/
private static class LazyHolder {
private static final LazySingLeton INSTANCE = new LazySingLeton();
}
private LazySingLeton(){};
/**
* 方法1
* @return
*/
public static final LazySingLeton getInstance() {
return LazyHolder.INSTANCE;
}
/**
* 方法2
* @return
*/
public static LazySingLeton newInstance() {
if(lazySingLeton ==null){
synchronized (LazySingLeton.class){
if (lazySingLeton ==null){
lazySingLeton = new LazySingLeton();
}
}
}
return lazySingLeton;
}
}
(1)为什么这样实现就是单例的?
因为这个类的实例化是靠静态内部类的静态常量实例化的。
INSTANCE 是常量,因此只能赋值一次;它还是静态的,因此随着内部类一起加载。
(2)这样实现有什么好处?
以前的懒汉式的代码有线程安全问题,需要加同步锁才能解决。
采用静态内部类实现的代码也是懒加载的,只有第一次使用这个单例的实例的时候才加载;同时不会有线程安全问题