class="p0">单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点
?
安全的单例模式:
?
?
/*
* @(#)Singleton.java 2014-8-1
*
* Copyright 2014 XXXX, Inc. All rights reserved.
*/
package com.fiberhome.singleton;
/**
* 单例对象
*
* @author liyan
* @version 2014-8-1
* @since 1.0
*/
public class Singleton
{
/**
* 构造器似有化保证外部不能进行new操作
*/
private Singleton(){}
/**
* 静态内部类保证线程安全
*
* @author liyan
* @version 2014-8-1
* @since 1.0
*/
private static class SingleHolder
{
final static Singleton INSTANCE = new Singleton();
}
/**
* 获取实例对象的方法
* @return
*/
public static Singleton getInstance()
{
return SingleHolder.INSTANCE;
}
/**
* 普通的类方法
*/
public void doSth(){}
}
?不安全的单例设计:
?
/* * @(#)SingletonUnSafe.java 2014-8-1 * * Copyright 2014 XXXX, Inc. All rights reserved. */ package com.fiberhome.singleton; /** * 非线程安全的单例设计 * * @author liyan * @version 2014-8-1 * @since 1.0 */ public class SingletonUnSafe { private static SingletonUnSafe sing; /** * 似有化构造器 */ private SingletonUnSafe() { } /** * 获取实例方法 * @return */ public static SingletonUnSafe getInstance() { /* * 首次初始化当前对象的一种假设情景 * 此时的代码块执行过程中的快照 * 两个实例化线程:Thrad1 and Thread2 */ //线程切换Thrad2线程执行此处执行判断分支为True即将进入 if (sing == null) { //Thrad1 刚进入代码块,还没有执行new指令 sing = new SingletonUnSafe(); } return sing; } }
?
测试用例
/*
* @(#)SingletonTest.java 2014-8-1
*
* Copyright 2014 XXXX, Inc. All rights reserved.
*/
package com.fiberhome.singleton;
import org.junit.Assert;
import org.junit.Test;
/**
* 测试单例
*
* @author liyan
* @version 2014-8-1
* @since 1.0
* @see
*/
public class SingletonTest
{
@Test
public void singletonTestCase()
{
Assert.assertEquals(Singleton.getInstance(), Singleton.getInstance());
}
}
?
?
? ? 为什么静态内部类可以保证初始化单例对象的时候是线程安全的?
? ? 静态内部类SingleHolder在获取其静态域的时候发送getstatic指令,虚拟机接收到这个指令立即对SingleHolder初始化,在调用SingleHolder构造器初始化之前首先完成其静态域的收集和初始化,静态域初始化完成以后是以单例的形式存在静态块区域的,随后调用构造器,构造器的初始化由jvm保证线程安全。所以静态内部类的这种初始化时线程安全的。
?
? ?关于类加载的时机
?
? ?类加载的“顺序”(非线性):加载->验证->准备->解析->初始化->使用-卸载
? ?在初始化阶段,虚拟机规范规定了只有4中情况必须立即对类进行初始化: ? ?
?
?
------------------------------------------补充概念------------------------------------
类加载器
“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作的加载木块叫做“类加载器”
类加载器的分类:
?
?
?
2014年8月1日 西安
hanily@msn.com
?
?