Chapter 6
第六章主要介绍如何使单例模式遇到多线程是安全的、正确的
- 立即加载/”饿汉式”
/**
* 立即加载单例模式/”饿汉式“
* Created by boboan on 2018/6/5.
*/
public class MyObject {
private static MyObject myObject = new MyObject();
public MyObject() {
}
public static MyObject getInstance(){
return myObject;
}
}
- 延迟加载/”懒汉式”
/**
* 延迟加载单例模式/"懒汉式"
*
* Created by boboan on 2018/6/5.
*/
public class MyObject2 {
private static MyObject2 myObject;
public MyObject2() {
}
public static MyObject2 getInstance(){
if (myObject != null) {
}else {
return myObject = new MyObject2();
}
return myObject;
}
}
但是这种方法在多线程的情况是错误的,出现多例的情况
/**
* 延迟加载单例模式/"懒汉式"
*
* Created by boboan on 2018/6/5.
*/
public class MyObject3 {
private static MyObject3 myObject;
public MyObject3() {
}
//设置同步方法效率比较低
//给方法加锁
synchronized public static MyObject3 getInstance(){
try {
if (myObject != null) {
}else {
Thread.sleep(3000);
return myObject = new MyObject3();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return myObject;
}
}
这种方法在多线程是错误的,可以通过加 synchronized 同步来解决
/**
* 延迟加载单例模式/"懒汉式"
*
* Created by boboan on 2018/6/5.
*/
public class MyObject4 {
private static MyObject4 myObject;
public MyObject4() {
}
public static MyObject4 getInstance(){
try {
if (myObject != null) {
}else {
synchronized (MyObject4.class) {
Thread.sleep(3000);
return myObject = new MyObject4();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return myObject;
}
}
synchronized 同步效率低,采用同步代码块,对关键代码同步效率稍微提升,但是多线程下还是无法解决
- DCL 双检查锁机制(推荐)
/**
* 延迟加载单例模式/"懒汉式"
*
* Created by boboan on 2018/6/5.
*/
public class MyObject5 {
private volatile static MyObject5 myObject;
public MyObject5() {
}
public static MyObject5 getInstance(){
try {
if (myObject != null) {
}else {
Thread.sleep(3000);
synchronized (MyObject5.class) {
if (myObject==null) {
myObject = new MyObject5();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return myObject;
}
}
DCL 双检查锁机制来解决问题,保证了不需要同步代码块的异步执行,又保证了单例的效果
- 静态内置类实现单例模式(推荐)
/**
* 静态内置类实现单例模式
*
* Created by boboan on 2018/6/5.
*/
public class MyObject6 {
private static class MyObjectHandler{
private static MyObject myObject = new MyObject();
}
public MyObject6() {
}
public static MyObject getInstance(){
return MyObjectHandler.myObject;
}
}
- 序列化与反序列化实现单例模式
**
* 序列化与反序列化实现单例模式
* 避免枚举类暴露
*
* Created by boboan on 2018/6/5.
*/
public class MyObject10 implements Serializable{
public static final long seriVersionUID = 898L;
public static class MyObjectHandler{
private static final MyObject10 myObject10= null;
}
private MyObject10(){
}
public static MyObject10 getInstance(){
return MyObjectHandler.myObject10;
}
protected Object readResolve(){
System.out.println("调用了 read 方法");
return MyObjectHandler.myObject10;
}
}
- static 代码块实现单例模式
/**
* static 代码块实现单例模式
*
* Created by boboan on 2018/6/5.
*/
public class MyObject7 {
private static MyObject myObject = null;
public MyObject7() {
}
static {
myObject = new MyObject();
}
public static MyObject getInstance(){
return myObject;
}
}
静态代码块在使用类的时候就执行了,利用此特性实现单例
- enum 枚举数据类型实现单例模式
/**
* 枚举类实现单例模式
* 避免枚举类暴露
*
* Created by boboan on 2018/6/5.
*/
public class MyObject9 {
public enum MyenumSingleton{
connectionFactory;
private int tag;
private MyenumSingleton() {
System.out.println("调用了");
tag = 1;
}
public int getTag(){
return tag;
}
}
public static int getComTag(){
return MyenumSingleton.connectionFactory.getTag();
}
}
使用枚举类时,构造方法会被自动调用。所以可以用来创建单例