- 饿汉式
单例模式 饿汉式类加载到内存后,实例化一个单例,jvm保证线程安全(都不能创建新的,所以安全,多线程都是安全的)
简单易用
缺点:不管是否用到,类加载时候就会实例化,浪费
一般项目开发中加载是用的Class.forName("") //将class加载到内存,但不实例化,此时,如果使用饿汉,就会消耗内存,所以产生了懒汉式
package DesignPatter.sington;
/**
* @author Susuper
* @version 1.0
* @date 2020/1/12 20:52
* @description
* 单例模式 饿汉式类加载到内存后,实例化一个单例,jvm保证线程安全(都不能创建新的,所以安全,多线程都是安全的)
* 简单易用
* 缺点:不管是否用到,类加载时候就会实例化,浪费
* 一般项目开发中加载是用的Class.forName("") //将class加载到内存,但不实例化,此时,如果使用饿汉,就会消耗内存,所以产生了懒汉式
*/
public class Mag01 {
private static final Mag01 INSTANCE = new Mag01();
private Mag01(){}; //构造方法私有化
private void show(){
System.out.println("饿汉式单例模式构建成功");
}
public static Mag01 getInstance(){ //必须设置为static,否则其它无法调用此方法
return INSTANCE;
}
public static void main(String[] args) {
Mag01 m = Mag01.getInstance();
Mag01 m2 = Mag01.getInstance();
System.out.println(m==m2);
}
}
- 饿汉式
lazy loading 懒汉式加载 需要的时候在加载,但是存在线程安全问题
package DesignPatter.sington;
/**
* @author Susuper
* @version 1.0
* @date 2020/1/12 21:02
* @description
* lazy loading 懒汉式加载
* 需要的时候在加载,但是存在线程安全问题
*/
public class Mag02 {
private static Mag02 INSTANCE = null;
private Mag02(){}
//加锁 由于这里是static对象 所以锁定的是Mag02 .class
public static synchronized Mag02 getInstance(){
if (INSTANCE==null){
//为了体现线程不安全的情况
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Mag02();
}
return INSTANCE;
}
public static void main(String[] args) {
//匿名内部类开启100个线程
// for(int i = 0;i<100;i++){
// new Thread(new Runnable() {
// @Override
// public void run() {
//
// }
// }).start();
// }
//lamda表达式对只有一个方法的匿名内部类的一个简化
for (int i =0;i<100;i++){
new Thread(()->{
System.out.println(Mag02.getInstance().hashCode());
}).start();
//当只有一句话的时候还可以简写
// new Thread(()->
// System.out.println(Mag02.getInstance().hashCode())
// ).start();
}
}
}
/**
new Runnable() {
@Override
public void run() {
}*/
/*
()->{
}*/
- 匿名内部类单例模式
完美方式之一
静态内部类方式
jvm负责保证线程安全
不理解的地方,在加载时候,Mag03Handle 是否会被直接加载进入,不理解,主要是无法测试class.forname理解还是不够
public class Mag03 {
//加载到内存后 并没有去实例化 静态变量
private static class Mag03Handle{
private static final Mag03 INSTANCE = new Mag03();
}
public static Mag03 getInstance(){
return Mag03Handle.INSTANCE;
}
}
- 枚举单例
由于枚举不存在构造方法,所以是单例的
不仅可以解决线程同步,还可以防止反序列化
public enum Mag04 {
INSTANCE;
public static void main(String[] args) {
for(int i = 0;i<100;i++){
new Thread(()->{
System.out.println(Mag04.INSTANCE.hashCode());
}).start();
}
}
}
···