[5]设计模式——单例模式_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > [5]设计模式——单例模式

[5]设计模式——单例模式

 2014/8/1 15:16:28  tsface  程序员俱乐部  我要评论(0)
  • 摘要:单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点安全的单例模式:/**@(#)Singleton.java2014-8-1**Copyright2014XXXX,Inc.Allrightsreserved.*/packagecom.fiberhome.singleton;/***单例对象**@authorliyan*@version2014-8-1*@since1.0*/publicclassSingleton
  • 标签:模式 设计 设计模式 单例模式

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中情况必须立即对类进行初始化: ? ?

  1. 遇到new?,getstatic,putstatic,invokestatic四条字节码指令。如果类没有进行初始化需要对其进行初 ? ?始化操作。 ? ?
  • new?:?使用new关键字实例化对象的时候 ?
  • getstatic?/putstatic?:?读取或者设置一个类的静态字段 ?
  • invokestatic?:调用一个类的静态方法
  1. 调用reflect包的方法对类进行反射调用的时候,如果没有初始化,需要对其进行初始化
  2. 初始化一个类的时候,返现其父类还没有初始化,则需要初始化其父类
  3. 当虚拟机启动的时候,用户需要指定一个要执行的主类,虚拟机会先初始化这个主类

?

?

------------------------------------------补充概念------------------------------------

类加载器

“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作的加载木块叫做“类加载器”

类加载器的分类:

  1. 启动类加载器(Bootstrap??ClassLoader):加载存在<JAVA_HOME>\lib?或者-Xbootclasspath目录中的,并且是虚拟机可识别的类库到虚拟机内存Java程序无法直接引用启动类加载器
  2. 扩展类加载器:加载<JAVA_HOME>\lib\ext目录中的,或者被java.ext.dirs系统变量指定的路径中的所有类库
  3. 应用程序类加载器:加载用户类路径(ClassPath)上指定的类库。

?

?

?

2014年8月1日 西安

hanily@msn.com

?

?

上一篇: jar文件查找站点 下一篇: 没有下一篇了!
发表评论
用户名: 匿名