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
?
?