1、饿汉式–两种
静态常量模式
/**
* 优点:避免多线程问题。
* 没有达到懒加载的问题
* 可能造成内存浪费
*/
public class HungaryManType1 {
private final static HungaryManType1 instance = new HungaryManType1();
private HungaryManType1(){
}
public static HungaryManType1 getInstance(){
return instance;
}
}
静态代码块
/**
* 同静态常量
*/
public class HungaryManType2 {
private final static HungaryManType2 instance;
static {
instance = new HungaryManType2();
}
private HungaryManType2(){
}
public static HungaryManType2 getInstance(){
return instance;
}
}
2、懒汉式–3种
第一种,常想到的形式
//懒汉式-线程不安全
/*
懒加载,不浪费
多线程下有线程安全问题
在实际开发中不能使用
*/
public class LazyManType1 {
private LazyManType1(){
}
private static LazyManType1 instance;
public static LazyManType1 getInstance(){
if (instance == null){
instance = new LazyManType1();
}
return instance;
}
}
第二种,同步方法
//懒汉式-线程安全,同步方法
/*
可解决线程不安全问题,效率太低,实际开发中不推荐
*/
public class LazyManType2 {
private LazyManType2(){
}
private static LazyManType2 instance;
public static synchronized LazyManType2 getInstance(){
if (instance == null){
instance = new LazyManType2();
}
return instance;
}
}
第三种,同步代码块,此方法并不能真正保证线程安全
//懒汉式-线程安全,同步代码块
/*
本意是对2改进,提升效率
实际上这样线程也不安全,
*/
public class LazyManType3 {
private LazyManType3(){
}
private static LazyManType3 instance;
public static LazyManType3 getInstance(){
if (instance == null){
// 在此处可能会同时有多个线程进到if快中,第一个线程实例化后,其他线程获得锁可继续实例化
synchronized (LazyManType3.class){
instance = new LazyManType3();
}
}
return instance;
}
}
3、双重检查DCL
//双重检查方式
/*
可以保证线程安全
推荐使用此单例设计模式
*/
public class DoubleChecking {
private DoubleChecking(){
}
private static volatile DoubleChecking instance;
public static DoubleChecking getInstance(){
if (instance == null){
synchronized (DoubleChecking.class){
if (instance == null){
instance = new DoubleChecking();
}
}
}
return instance;
}
}
4、枚举类形式
//推荐使用,
/*
不仅能够避免多线程,还能防止反序列化方式
*/
enum EnumerationClass {
INSTANCE;
public void sayOk(){
System.out.println("ok~");
}
}
5、静态内部类形式
//静态内部类 --- 推荐使用
//
public class StaticInsideClass {
private StaticInsideClass(){
}
/*
1、当StaticInsideClass装载时,静态内部类不会被装载
2、当外部类调用instance时才加载静态内部类,
3、使用时也安全
*/
private static class InsideClass{
private final static StaticInsideClass instance = new StaticInsideClass();
}
public static StaticInsideClass getInstance(){
return InsideClass.instance;
}
}