1、动态初始化
/**
饿汉式
类加载到内存后,就实例化一个单例,jvm保障线程平安
简略实用,举荐应用
惟一毛病:不论用到与否,类加载时就实现实例化
(话说你不必的,你转载它干啥)
个别这种就够用了
*/
public class Mgr01 {
【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年99元
private static final Mgr01 INSTANCE = new Mgr01();
private Mgr01(){}
public static Mgr01 getInstance(){return INSTANCE; }
public void m(){
System.out.println("m");
}
public static void main(String[] args){
Mgr01 m1 = Mgr01.getInstance();
Mgr01 m2 = Mgr01.getInstance();
System.out.println(m1 == m2);
}
}
//这种写法跟Mgr01一个意思
public class Mgr02 {
private static final Mgr02 INSTANCE;
static {
INSTANCE = new Mgr02();
}
private Mgr02(){}
public static Mgr02 getInstance(){return INSTANCE;}
public void m(){
System.out.println("m");
}
public static void main(String[] args) {
Mgr02 m1 = Mgr02.getInstance();
Mgr02 m2 = Mgr02.getInstance();
System.out.println(m1 == m2);
}
}
2、加锁+双重查看~~~~
/**
lazy loading
也称懒汉式
尽管达到了按需初始化的目标,然而带来线程不平安问题
能够通过synchronize解决,这个是能够失常应用的,但也带来效率降落问题
*/
public class Mgr04 {
private static volatile Mgr04 INSTANCE;
private Mgr04() {
}
//这个synchronized锁定的是Mgr04.class,因为锁是加在static下面的
public static synchronized Mgr04 getInstance(){
if(INSTANCE == null){
try {
Thread.sleep(1);
}catch (InterruptedException e){
e.printStackTrace();
}
INSTANCE = new Mgr04();
}
return INSTANCE;
}
public void m(){
System.out.println("m");
}
public static void main(String[] args) {
for(int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(Mgr04.getInstance().hashCode());
}).start();
}
}
}
/**
lazy loading
也称懒汉式
尽管达到了按需初始化的目标,然而带来线程不平安问题
能够通过synchronize解决,这个是能够失常应用的,但也带来效率降落
这是一种完满写法
*
*/
public class Mgr06 {
private static volatile Mgr06 INSTANCE;
private Mgr06() {
}
public static Mgr06 getInstance(){
if(INSTANCE == null){
//双重查看
synchronized(Mgr06.class){
if(INSTANCE == null){
try {
Thread.sleep(1);
}catch (InterruptedException e){
e.printStackTrace();
}
INSTANCE = new Mgr06();
}
}
}
return INSTANCE;
}
public void m(){
System.out.println("m");
}
public static void main(String[] args) {
for(int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(Mgr06.getInstance().hashCode());
}).start();
}
}
}
3、动态外部类形式
/**
动态外部类形式
JVM保障单例
胜在动态的货色只加载一次,并且加载外部类时不会加载外部类,这样能够实现懒加载
比Mgr01完满,
*/
public class Mgr07 {
private Mgr07(){}
private static class Mgr07Holder{
private final static Mgr07 INSTANCE = new Mgr07();
}
public static Mgr07 getInstance(){
return Mgr07Holder.INSTANCE;
}
public void m(){
System.out.println("m");
}
public static void main(String[] args) {
for(int i = 0; i< 100; i++){
new Thread(()->{
System.out.println(Mgr07
.getInstance().hashCode());
}).start();
}
}
}
4、枚举模式
/**
不仅能够解决线程同步,还能够避免反序列化
*/
public enum Mgr08 {
INSTANCE;
public void m(){}~~~~
public static void main(String[] args) {
for(int i = 0; i< 100; i++){
new Thread(()->{
System.out.println(Mgr08.INSTANCE.hashCode());
}).start();
}
}
}