单例模式实现的方式:
1、恶汉式:类加载到内存后,就实例化一个实例,JVM保障线程安全(简单实用,推荐)。(
缺点:不管用到与否类装载时就完成实例化)
2、懒汉式:虽然达到了初始化的目的,但是线程不安全
解决方式:
①、通过synchronized修饰,但是效率会下降;
②、通过synchronized修饰减少同步代码块的方式,但是效率会下降;
③、双重校验
3、静态内部类方式:JVM保障线程安全(加载外部类的时候不会加载内部类)
4、枚举类的方式:不仅可以解决线程同步的问题,还可以防止反序列化
1、恶汉式:
public class Singleton_001_EvilMan {
private static final Singleton_001_EvilMan INSTANCE = new Singleton_001_EvilMan();
// 方式二
// private static final Singleton_001_EvilMan INSTANCE;
// static {
// INSTANCE = new Singleton_001_EvilMan();
// }
public static Singleton_001_EvilMan getInstance() {
return INSTANCE;
}
private Singleton_001_EvilMan() {}
public void show(){
System.out.println("hello");
}
public static void main(String[] args) {
Singleton_001_EvilMan singleton_001_eHan = Singleton_001_EvilMan.getInstance();
Singleton_001_EvilMan singleton_001_eHan1 = Singleton_001_EvilMan.getInstance();
singleton_001_eHan.show();
System.out.println(singleton_001_eHan == singleton_001_eHan1);
}
}
运行结果:
2、懒汉式:
public class Singleton_002_LazyMan {
private static Singleton_002_LazyMan INSTANCE;
private Singleton_002_LazyMan() {}
// ①、通过synchronized修饰,但是效率会下降
public static /*synchronized*/ Singleton_002_LazyMan getInstance() {
if(INSTANCE == null) {
// ②、妄图通过减小同步代码块的方式提高效率,然后不可行
synchronized (Singleton_002_LazyMan.class) {
// ③、双重检查 可以解决
if(INSTANCE == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton_002_LazyMan();
}
}
}
return INSTANCE;
}
public void show() {
System.out.println("lazyMan");
}
public static void main(String[] args) {
for(int i=0; i<10; i++) {
new Thread(()->
System.out.println(Singleton_002_LazyMan.getInstance().hashCode())
).start();
}
}
}
运行结果:
3、静态内部类方式:
public class Singleton_003_StaticInternalClass {
private Singleton_003_StaticInternalClass(){}
private static class Singleton_003_StaticInternalClassHolder {
private final static Singleton_003_StaticInternalClass INSTANCE = new Singleton_003_StaticInternalClass();
}
public static Singleton_003_StaticInternalClass getInstance() {
return Singleton_003_StaticInternalClassHolder.INSTANCE;
}
public static void show() {
System.out.println("StaticInternalClass");
}
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
new Thread(()->{
System.out.println(Singleton_003_StaticInternalClass.getInstance().hashCode());
Singleton_003_StaticInternalClass.show();
}).start();
}
}
}
运行结果:
4、枚举类
public enum Singleton_004 {
INSTANCE;
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
new Thread(()->{
System.out.println(Singleton_004.INSTANCE.hashCode());
}).start();
}
}
}
运行结果: