深入单例模式 java,深入单例模式四

Java代码 icon_copy.gif

privatestaticClass getClass(String classname)

throwsClassNotFoundException {

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

if(classLoader ==null)

classLoader = Singleton.class.getClassLoader();

return(classLoader.loadClass(classname));

}

}

private static Class getClass(String classname)

throws ClassNotFoundException {

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

if(classLoader == null)

classLoader = Singleton.class.getClassLoader();

return (classLoader.loadClass(classname));

}

}

这个方法会尝试把当前的线程与那个类载入器相关联;如果classloader为null,这个方法会使用与装入单例类基类的那个类载入器。这个方法可以用Class.forName()代替。

序列化

如果你序列化一个单例类,然后两次重构它,那么你就会得到那个单例类的两个实例,除非你实现readResolve()方法,像下面这样:

例12 一个可序列化的单例类

Java代码 icon_copy.gif

importorg.apache.log4j.Logger;

publicclassSingletonimplementsjava.io.Serializable {

publicstaticSingleton INSTANCE =newSingleton();

protectedSingleton() {

// Exists only to thwart instantiation.

}

privateObject readResolve() {

returnINSTANCE;

}

}

import org.apache.log4j.Logger;

public class Singleton implements java.io.Serializable {

public static Singleton INSTANCE = new Singleton();

protected Singleton() {

// Exists only to thwart instantiation.

}

private Object readResolve() {

return INSTANCE;

}

}

上面的单例类实现从readResolve()方法中返回一个唯一的实例;这样无论Singleton类何时被重构,它都只会返回那个相同的单例类实例。

例13测试了例12的单例类:

例13 测试一个可序列化的单例类

Java代码 icon_copy.gif

importjava.io.*;

importorg.apache.log4j.Logger;

importjunit.framework.Assert;

importjunit.framework.TestCase;

publicclassSingletonTestextendsTestCase {

privateSingleton sone =null, stwo =null;

privatestaticLogger logger = Logger.getRootLogger();

publicSingletonTest(String name) {

super(name);

}

publicvoidsetUp() {

sone = Singleton.INSTANCE;

stwo = Singleton.INSTANCE;

}

publicvoidtestSerialize() {

logger.info("testing singleton serialization...");

      writeSingleton();

Singleton s1 = readSingleton();

Singleton s2 = readSingleton();

Assert.assertEquals(true, s1 == s2);   }

privatevoidwriteSingleton() {

try{

FileOutputStream fos =newFileOutputStream("serializedSingleton");

ObjectOutputStream oos =newObjectOutputStream(fos);

Singleton s = Singleton.INSTANCE;

oos.writeObject(Singleton.INSTANCE);

oos.flush();

}

catch(NotSerializableException se) {

logger.fatal("Not Serializable Exception: "+ se.getMessage());

}

catch(IOException iox) {

logger.fatal("IO Exception: "+ iox.getMessage());

}

}

privateSingleton readSingleton() {

Singleton s =null;

try{

FileInputStream fis =newFileInputStream("serializedSingleton");

ObjectInputStream ois =newObjectInputStream(fis);

s = (Singleton)ois.readObject();

}

catch(ClassNotFoundException cnf) {

logger.fatal("Class Not Found Exception: "+ cnf.getMessage());

}

catch(NotSerializableException se) {

logger.fatal("Not Serializable Exception: "+ se.getMessage());

}

catch(IOException iox) {

logger.fatal("IO Exception: "+ iox.getMessage());

}

returns;

}

publicvoidtestUnique() {

logger.info("testing singleton uniqueness...");

Singleton another =newSingleton();

logger.info("checking singletons for equality");

Assert.assertEquals(true, sone == stwo);

}

}

import java.io.*;

import org.apache.log4j.Logger;

import junit.framework.Assert;

import junit.framework.TestCase;

public class SingletonTest extends TestCase {

private Singleton sone = null, stwo = null;

private static Logger logger = Logger.getRootLogger();

public SingletonTest(String name) {

super(name);

}

public void setUp() {

sone = Singleton.INSTANCE;

stwo = Singleton.INSTANCE;

}

public void testSerialize() {

logger.info("testing singleton serialization...");

writeSingleton();

Singleton s1 = readSingleton();

Singleton s2 = readSingleton();

Assert.assertEquals(true, s1 == s2); }

private void writeSingleton() {

try {

FileOutputStream fos = new FileOutputStream("serializedSingleton");

ObjectOutputStream oos = new ObjectOutputStream(fos);

Singleton s = Singleton.INSTANCE;

oos.writeObject(Singleton.INSTANCE);

oos.flush();

}

catch(NotSerializableException se) {

logger.fatal("Not Serializable Exception: " + se.getMessage());

}

catch(IOException iox) {

logger.fatal("IO Exception: " + iox.getMessage());

}

}

private Singleton readSingleton() {

Singleton s = null;

try {

FileInputStream fis = new FileInputStream("serializedSingleton");

ObjectInputStream ois = new ObjectInputStream(fis);

s = (Singleton)ois.readObject();

}

catch(ClassNotFoundException cnf) {

logger.fatal("Class Not Found Exception: " + cnf.getMessage());

}

catch(NotSerializableException se) {

logger.fatal("Not Serializable Exception: " + se.getMessage());

}

catch(IOException iox) {

logger.fatal("IO Exception: " + iox.getMessage());

}

return s;

}

public void testUnique() {

logger.info("testing singleton uniqueness...");

Singleton another = new Singleton();

logger.info("checking singletons for equality");

Assert.assertEquals(true, sone == stwo);

}

}

前面这个测试案例序列化例12中的单例类,并且两次重构它。然后这个测试案例检查看是否被重构的单例类实例是同一个对象。下面是测试案例的输出:

Java代码 icon_copy.gif

Buildfile: build.xml

init:

[echo] Build20030422(22-04-200311:32)

compile:

run-test-text:

[java] .INFO main: testing singleton serialization...

[java] .INFO main: testing singleton uniqueness...

[java] INFO main: checking singletonsforequality

[java] Time:0.1

[java] OK (2tests)

Buildfile: build.xml

init:

[echo] Build 20030422 (22-04-2003 11:32)

compile:

run-test-text:

[java] .INFO main: testing singleton serialization...

[java] .INFO main: testing singleton uniqueness...

[java] INFO main: checking singletons for equality

[java] Time: 0.1

[java] OK (2 tests)

单例模式结束语

单例模式简单却容易让人迷惑,特别是对于Java的开发者来说。在这篇文章中,作者演示了Java开发者在顾及多线程、类载入器和序列化情况如何实现单例模式。作者也展示了你怎样才能实现一个单例类的注册表,以便能够在运行期指定单例类。

posted on 2008-05-05 22:12 bcterry 阅读(38) 评论(0)  编辑  收藏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux下配置SS5(SOCK5)代理服务

SOCK5代理服务器 官网: http://ss5.sourceforge.net/ yum -y install gcc gcc-c automake make pam-devel openldap-devel cyrus-sasl-devel 一、安装 # tar xvf ss5-3.8.9-5.tar.gz # cd ss5-3.8.9-5 # ./configure && make && make install 二、修改配置文…

去除list集合中重复项的几种方法

因为用到list&#xff0c;要去除重复数据&#xff0c;尝试了几种方法。记录于此。。。 测试数据&#xff1a; List<string> li1 new List<string> { "8", "8", "9", "9" ,"0","9"};List<string&g…

Crystal Reports第一张报表

新建一个网站项目&#xff0c;1. 设置数据库 从服务器资源管理器中&#xff0c;数据连接中添加新连接&#xff0c;用Microsoft Access数据库文件作为数据提供程序&#xff0c;连接上Crystal Reports的用例的数据库Xtreme2. 创建新Crystal Reports报表 在工程项目中添加一个…

品牌推广前期要进行哪些针对性的步骤?

企业在品牌推广前需要制订一系列有针对性和连续性的步骤&#xff0c;这些步骤定睛于长期策略&#xff0c;而且要适应目标客户的使用方式和习惯。在企业内部导入品牌VI是前提&#xff0c;外部的宣传则是强调品牌所宣扬的内涵和精神实质&#xff0c;总体来说&#xff0c;这只是一…

php的set 容器,关于STL中set容器的一些总结

1.关于setC STL 之所以得到广泛的赞誉&#xff0c;也被很多人使用&#xff0c;不只是提供了像vector, string, list等方便的容器&#xff0c;更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组&#xff0c;list封装了链表&#xff0c;map和set…

导入导出报错

导入导出报错&#xff1a;另&#xff1a;右键--共享&#xff1a;停止共享&#xff1b;可能无效。此时&#xff0c;可以通过修改文件夹的权限&#xff0c;来达到停止共享的目的&#xff1b;转载于:https://www.cnblogs.com/chenjx/p/7107336.html

mysql复制的工作原理及主从复制的实现

mysql的复制功能主要有3个步骤主服务器将改变记录到二进制日志中&#xff0c;&#xff08;这些记录叫做二进制日志事件&#xff09;从服务器将主服务器的二进制日志事件拷贝到它的中继日志中从服务器重做中继日志中的事件。该过程的第一部分就是主服务器记录二进制日志&#xf…

Office 365 系列之九:配置和体验 Exchange 和 Lync

在之前的篇章中&#xff0c;我们已经安装好 Office 365 Pro Plus 和通过 O365 订阅激活了。接下来我们来看看具体怎么配置和使用 Exchange 和 Skype, 这部分内容对于学习过 Exchange Server 2016 和 Skype For Business 2015 的同学来说就很简单了。通过 OWA 访问 Exchange 对于…

netflix_Netflix的Polynote

netflixNetflix open source Polynote is a new notebook environment and was born out of the necessity to accelerate data science experimentation at Netflix.Netflix开源Polynote是一种新的笔记本环境&#xff0c;其诞生是出于加速Netflix数据科学实验的需要。 Over t…

图片管理程序(Java)

图片管理程序 gitee完整代码下载 github完整代码下载 华南农业大学课程设计作品&#xff08;99分&#xff09; 问题描述 题目目的是编写一个能够对数字像片进行管理的应用程序。 程序能够显示的图片格式包括,.JPG、.JPEG、.GIF、.PNG、和.BMP。 图像文件尺寸,要求能够处理从…

气流与路易吉,阿戈,MLFlow,KubeFlow

任务编排工具和工作流程 (Task orchestration tools and workflows) Recently there’s been an explosion of new tools for orchestrating task- and data workflows (sometimes referred to as “MLOps”). The quantity of these tools can make it hard to choose which o…

模拟操作系统(Java)

gitee完整代码下载 github完整代码下载 一、 需求分析 模拟一个采用多道程序设计方法的单用户操作系统&#xff0c;该操作系统包括进程管理、存储管理、设备管理、文件管理和用户接口四部分。预计程序所能达到的功能&#xff1a; 进程管理模拟&#xff1a;实现操作系统进程管…

数据库面试复习_数据科学面试复习

数据库面试复习大面试前先刷新 (REFRESH BEFORE THE BIG INTERVIEW) 介绍 (Introduction) I crafted this study guide from multiple sources to make it as comprehensive as possible. This guide helped me prepare for both the technical and behavioral aspects of the …

hibernate缓存

&#xff08;转自&#xff1a;http://www.cnblogs.com/java-class/p/6108175.html&#xff09; 阅读目录 1. 为什么要用 Hibernate 缓存&#xff1f;2. 项目实战3. Hibernate 缓存原理回到顶部1. 为什么要用 Hibernate 缓存&#xff1f; Hibernate是一个持久层框架&#xff0c;…

分布与并行计算—用任务管理器画CPU正弦曲线(Java)

class drawSin implements Runnable{Overridepublic void run() {final double SPLIT 0.01;// 角度的分割final int COUNT (int) (2 / SPLIT);// 2PI分割的次数&#xff0c;也就是2/0.01个&#xff0c;正好是一周final double PI Math.PI;final int interval 100;// 时间间…

Asp.net mvc中使用配置Unity

第一步&#xff1a;添加unity.mvc 第二步&#xff1a;在添加之后会在app_start中生成UnityConfig.cs&#xff0c;UnityMvcActivator.cs 第三步&#xff1a;使用 第四步&#xff1a;效果展示 转载于:https://www.cnblogs.com/WJ--NET/p/7117839.html

正确认识 Vista 激活期限

当我们在安装 Vista 时&#xff0c;可以不输入序列号进行安装&#xff0c;这和以往的操作系统安装有所不同&#xff0c;我们不必再为安装系统时找不到我们的序列号标签而发愁。如果不输入序列号而继续安装系统&#xff0c;那么系统将提示我们有30天的激活期限&#xff01;这里的…

Oracle使用hs odbc连接mssql2008

1.创建odbc 2.在 product\11.2.0\dbhome_1\hs\admin\ 下拷贝initdg4odbc,把名字改为initcrmsql&#xff08;init所建odbc的名称&#xff09; HS_FDS_CONNECT_INFO crmsql #odbc名称 HS_FDS_TRACE_LEVEL 0 HS_FDS_RECOVERY_ACCOUNTsa #要连接的数据库名称 HS_FDS_RECOVERY_PWD…

【NGN学习笔记】6 代理(Proxy)和背靠背用户代理(B2BUA)

1. 什么是Proxy模式&#xff1f; 按照RFC3261中的定义&#xff0c;Proxy服务器是一个中间的实体&#xff0c;它本身即作为客户端也作为服务端&#xff0c;为其他客户端提供请求的转发服务。一个Proxy服务器首先提供的是路由服务&#xff0c;也就是说保证请求被发到更加”靠近”…

《人人都该买保险》读书笔记

内容目录&#xff1a; 1.你必须知道的保险知识 2.家庭理财的必需品 3.保障型保险产品 4.储蓄型保险产品 5.投资型保险产品 6.明明白白买保险 现在我所在的公司Manulife是一家金融保险公司&#xff0c;主打业务就是保险&#xff0c;因此我需要熟悉一下保险的基础知识&#xff0c…