单例模式
饿汉式:
java
package single;
// 饿汉式单例
public class hungry {
// 饿汉式有可能会浪费内存
// 因为饿汉式在生成对象时,就创建了所有的空间
// 单例模式构造器私有
private hungry(){
}
private final static hungry HUNGRY = new hungry();
public static hungry getInstance(){
return HUNGRY;
}
}
普通懒汉式:
java
package single;
// 懒汉式单例模式
public class lazy {
// 单例模式构造器私有
private lazy(){
System.out.println(Thread.currentThread().getName()+" gotten");
}
// 普通懒汉式,在并发下可能会出现问题
private static lazy lazyMan;
public static lazy getInstance(){
if (lazyMan == null){
lazyMan = new lazy();
}
return lazyMan;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(()->{
lazy.getInstance();
}).start();
}
}
}
使用synchronized与volatile的懒汉式单例
java
package single;
// 懒汉式单例模式
public class lazy {
// 单例模式构造器私有
private lazy(){
System.out.println(Thread.currentThread().getName()+" gotten");
}
// 双重检测锁模式的懒汉式单例
private volatile static lazy lazyMan;
private static lazy getInstance(){
if(lazyMan == null){
synchronized(lazy.class){
if (lazyMan == null){
lazyMan = new lazy();// 不是一个原子性操作
/**
* 1、分配内存空间
* 2、执行构造方法,初始化对象
* 3、把这个对象指向这个空间
* 该过程可能发生指令重排
* 因此必须让对象加volatile生成内存屏障
*/
}
}
}
return lazyMan;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(()->{
lazy.getInstance();
}).start();
}
}
}
静态内部类
java
package single;
// 静态内部类 (不安全)
public class Holder {
// 单例模式构造器私有
private Holder(){
}
public static Holder getInstance(){
return InnerClass.HOLDER;
}
public static class InnerClass{
private static final Holder HOLDER = new Holder();
}
}
以上单例都不安全,使用反射即可破坏单例
使用枚举单例模式,反射无法破坏枚举单例