作用:
节省内存和计算
保证结果正确
方便管理
适用场景:
1.无状态的工具类(日志工具类)
2.全局信息类(记录网站的访问次数)
几种写法:
1.饿汉式(饿汉式-静态常量-可用)
public class Singleton1 {
private final static Singleton1 INSTANCE = new Singleton1();
public static Singleton1 getINSTANCE() {
return INSTANCE;
}
public Singleton1() {
}
}
2.饿汉式(饿汉式-静态代码块-可用)
public class Singleton2 {
private final static Singleton2 INSTANCE;
static {
INSTANCE = new Singleton2();
}
public static Singleton2 getINSTANCE() {
return INSTANCE;
}
public Singleton2() {
}
}
3.懒汉式(线程不安全-不可用)
public class Singleton3 {
private static Singleton3 instance;
public Singleton3() {
}
public static Singleton3 getInstance() {
if(instance == null){
instance = new Singleton3();
}
return instance;
}
}
4.懒汉式(线程安全,同步方法)不推荐用 效率太低 在3上加synchronized修饰
5.懒汉式(线程不安全,同步代码块用)不可用
public class Singleton5 {
private static Singleton5 instance;
public Singleton5() {
}
public static Singleton5 getInstance() {
if(instance == null){
synchronized (Singleton5.class){
instance = new Singleton5();
}
}
return instance;
}
}
6.双重检查 推荐
/**
* 双重检查 推荐面试使用
* 优点:线程安全;延迟加载;效率较高
* 为什么要double-check
* 1.线程安全
* 2.单check行不行?
* 3.性能问题
* 用volatile修饰 才能保证安全
* 1.新建对象实际上有3个步骤
*
*/
public class Singleton6 {
private static Singleton6 instance;
public Singleton6() {
}
public static Singleton6 getInstance() {
if(instance == null){
synchronized (Singleton6.class){
if (instance == null) {
instance = new Singleton6();
}
}
}
return instance;
}
}
7.静态内部类【推荐用】
public class Singleton7 {
private static Singleton7 instance;
public Singleton7() {
}
private static class SingletonInstance{
private static final Singleton7 INSTANCE = new Singleton7();
}
public static Singleton7 getInstance() {
return SingletonInstance.INSTANCE;
}
}
8.枚举
public enum Singleton8 {
INSTANCE;
public void whatever(){}
}
饿汉:简单。但是没有懒加载
懒汉:有线程安全问题
静态内部类:可用
双重检查:面试用
枚举:最好(写法简单、线程安全有保障、避免反序列化破坏单例)