您的位置:首页 > 编程语言 > Java开发

Java 单例模式

2016-07-27 00:00 357 查看
#单例模式

##一.代码实现
###1.饿汉式

public class Singleton1 {

private static final Singleton1 INSTANCE = new 	Singleton1();
private Singleton1(){}
public static Singleton1 getInstance(){
return INSTANCE;
}
}

声明为静态类变量,在类加载时初始化,因此不会有线程安全问题,若未被调用则会造成资源浪费。

public class Singleton3 {
private static Singleton3 SINGLETON=null;
private Singleton3() {}
static{
SINGLETON=new Singleton3();
}
public Singleton3 getInstance(){
return SINGLETON;
}
}

使用静态代码块,在类加载时初始化,因此不会有线程安全问题,若未被调用则会造成资源浪费。
###2.懒汉式

public class Singleton2 {
private static Singleton2 instance = null;
private Singleton2() {
}
public static Singleton2 getInstance() {
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}

延迟加载,但多线程情况下会产生线程安全问题

public class Singleton4 {
private static Singleton4 instance = null;
private Singleton4() {
}
public static synchronized Singleton4 getInstance() {
if (instance == null) {
instance = new Singleton4();
}
return instance;
}
}

延迟加载,多线程情况下不会产生线程安全问题,但效率不高

public class Singleton5 {
private static Singleton5 instance = null;
private Singleton5() {
}
public static Singleton5 getInstance() {
if (instance == null) {
synchronized (Singleton5.class) {
if (instance == null) {
instance = new Singleton5();
}
}
}
return instance;
}
}

双检索机制,延迟加载,多线程情况下不会产生线程安全问题,只在第一次创建时进行同步。但由于JVM底层内部模型原因,偶尔会出现问题。

public class Singleton5 {
private static volatile Singleton5 instance = null;
private Singleton5() {
}
public static Singleton5 getInstance() {
if (instance == null) {
synchronized (Singleton5.class) {
if (instance == null) {
instance = new Singleton5();
}
}
}
return instance;
}

将instance声明为volatile即可排除问题,试用与JDK1.5以后
###3.静态内部类

public class Singleton6 {
private Singleton6() {
}
private static class SingletonInstance {
private static final Singleton6 INSTANCE = new Singleton6();
}
public static Singleton6 getInstance() {
return SingletonInstance.INSTANCE;
}
}

在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。且类的静态属性只在第一次类加载时初始化,所以是线程安全的。

public enum Singleton7 {
INSTANCE;
}

枚举的方式

###4.用ThreadLocal实现

public class Singleton8 {
private static final ThreadLocal threadLocal = new ThreadLocal();
private static Singleton8 singleton8;

private Singleton8() {
}

public static Singleton8 getInstance() {
if (threadLocal.get() == null) {
// 每个线程第一次都会调用
createInstance();
}
return singleton8;
}
private static final void createInstance() {
synchronized (Singleton8.class) {
if (singleton8 == null) {
singleton8 = new Singleton8();
}
}
threadLocal.set(threadLocal);
}
}

每个线程借助于ThreadLocal,用来标示每个线程是否已访问过,如果访问过,则不再需要走同步块,提高了一定的效率。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: