当前位置:首页 > 开发 > 编程语言 > 设计模式 > 正文

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

发表于: 2014-08-01   作者:tsface   来源:转载   浏览:
摘要: 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点   安全的单例模式:     /* * @(#)Singleton.java 2014-8-1 * * Copyright 2014 XXXX, Inc. All rights reserved. */ package com.fiberhome.singleton;

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点

 

安全的单例模式:

 

 

/*
 * @(#)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

 

 

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
问题聚焦: 让类自身负责保存它的唯一实例,并且保证没有其他实例可以被创建。 单例模式使用起来比
1 前言 在程序开发过程中,我们总会遇到一些情况,要求我们有一个类只有一个实例,这种情况下,我们
转自: http://baike.baidu.com/link?url=UcxeuDIltmc8Rh6s1s4I8gvjWbKa8EAVDmMlZhDwIwEZNhSVCuHB_o
今天看视频,又讲到了单例模式。回忆起第一次去面试的时候,面试官问是否用过单例模式,我很肯定的
java模式之单例模式: 单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例
单例模式 单例模式"> 单例模式有两种写法: 饿汉式: /** * * 此类描述的是: 单例模式 * 饿汉式
摘要 本文将主要讲解创建型模式中的单例模式先来讲解,因为单例模式是最简单也是最容易理解的设计模
单例模式的定义 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 生活中的例
单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。通常我们可以让一个
1 初识单例模式: 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点 结构: 参考实现:
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号