Java-单例模式(singleton)-转载
概念:
java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
首先看一个经典的单例实现。
public class Singleton {
private static Singleton uniqueInstance = null;
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// Other methods...
}
Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)
但是以上实现没有考虑线程安全问题。所谓线程安全是指:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个Singleton实例。
1 public class TestStream {
2 private String name;
3 public String getName() {
4 return name;
5 }
6 public void setName(String name) {
7 this.name = name;
8 }
9 //该类只能有一个实例
10 private TestStream(){} //私有无参构造方法
11 //该类必须自行创建
12 //有2种方式
13 /*private static final TestStream ts=new TestStream();*/
14 private static TestStream ts1=null;
15 //这个类必须自动向整个系统提供这个实例对象
16 public static TestStream getTest(){
17 if(ts1==null){
18 ts1=new TestStream();
19 }
20 return ts1;
21 }
22 public void getInfo(){
23 System.out.println("output message "+name);
24 }
25 }
1 public class TestMain {
2 public static void main(String [] args){
3 TestStream s=TestStream.getTest();
4 s.setName("张孝祥");
5 System.out.println(s.getName());
6 TestStream s1=TestStream.getTest();
7 s1.setName("张孝祥");
8 System.out.println(s1.getName());
9 s.getInfo();
10 s1.getInfo();
11 if(s==s1){
12 System.out.println("创建的是同一个实例");
13 }else if(s!=s1){
14 System.out.println("创建的不是同一个实例");
15 }else{
16 System.out.println("application error");
17 }
18 }
19 }
运行结果:
张孝祥
张孝祥
output message 张孝祥
output message 张孝祥
创建的是同一个实例
结论:由结果可以得知单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象。
1.饿汉式单例类
1 //饿汉式单例类.在类初始化时,已经自行实例化
2 public class Singleton1 {
3 //私有的默认构造子
4 private Singleton1() {}
5 //已经自行实例化
6 private static final Singleton1 single = new Singleton1();
7 //静态工厂方法
8 public static Singleton1 getInstance() {
9 return single;
10 }
11 }
2.懒汉式单例类
1 //懒汉式单例类.在第一次调用的时候实例化
2 public class Singleton2 {
3 //私有的默认构造子
4 private Singleton2() {}
5 //注意,这里没有final
6 private static Singleton2 single=null;
7 //静态工厂方法
8 public synchronized static Singleton2 getInstance() {
9 if (single == null) {
10 single = new Singleton2();
11 }
12 return single;
13 }
14 }
3.登记式单例类
1 import java.util.HashMap;
2 import java.util.Map;
3 //登记式单例类.
4 //类似Spring里面的方法,将类名注册,下次从里面直接获取。
5 public class Singleton3 {
6 private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
7 static{
8 Singleton3 single = new Singleton3();
9 map.put(single.getClass().getName(), single);
10 }
11 //保护的默认构造子
12 protected Singleton3(){}
13 //静态工厂方法,返还此类惟一的实例
14 public static Singleton3 getInstance(String name) {
15 if(name == null) {
16 name = Singleton3.class.getName();
17 System.out.println("name == null"+"--->name="+name);
18 }
19 if(map.get(name) == null) {
20 try {
21 map.put(name, (Singleton3) Class.forName(name).newInstance());
22 } catch (InstantiationException e) {
23 e.printStackTrace();
24 } catch (IllegalAccessException e) {
25 e.printStackTrace();
26 } catch (ClassNotFoundException e) {
27 e.printStackTrace();
28 }
29 }
30 return map.get(name);
31 }
32 //一个示意性的商业方法
33 public String about() {
34 return "Hello, I am RegSingleton.";
35 }
36 public static void main(String[] args) {
37 Singleton3 single3 = Singleton3.getInstance(null);
38 System.out.println(single3.about());
39 }
40 }
Java-单例模式(singleton)-转载的更多相关文章
- 设计模式 单例模式(Singleton) [ 转载2 ]
设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...
- 设计模式 单例模式(Singleton) [ 转载 ]
设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...
- Java单例模式(转载)
原文地址:1:http://www.cnblogs.com/hupp/p/4487521; 2:http://cantellow.javaeye.com/blog/838473 先罗列五种单例模式的实 ...
- Java单例模式(Singleton)以及实现
一. 什么是单例模式 因程序需要,有时我们只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计. 二. 单例模式的特点 1. 单例模式只能有一个实例. 2. 单例类必须创建 ...
- java 单例模式(转载)
http://www.cnblogs.com/whgw/archive/2011/10/05/2199535.html Java中单例模式是一种常见的设计模式,可分为三种:懒汉式单例.饿汉式单例.登记 ...
- 深入Java单例模式【转载】
在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下. 所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在 ...
- JAVA设计模式-单例模式(Singleton)线程安全与效率
一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...
- java设计模式之 单例模式 Singleton
static 的应用 单例模式 Singleton 单例:保证一个类在系统中最多只创建一个实例. 好处:由于过多创建对象实例,会产生过多的系统垃圾,需要GC频繁回收,由于GC会占用较大的系统资源,所有 ...
- 创建模式--单例模式Singleton(JAVA)
创建模式之单例模式 在面试时经常会有人问单例模式,单例模式是在整个系统运行中仅且仅有一个实例,在被调用.我们熟知的Calendar就是这种, Calendar.newIns ...
- JAVA:将反射技术应用于工厂模式(Factory)和单例模式(Singleton)的简单代码
反射技术大量用于Java设计模式和框架技术,最常见的设计模式就是工厂模式(Factory)和单例模式(Singleton). 参考URL: http://blog.csdn.net/xiaohai79 ...
随机推荐
- Linux操作系统安装JDK
1.利用winSCP将要安装的jdk包传到Linux上. 2.命令 tar -zxvf [jdk的安装包],安装包须是tar的包才行. ep:tar -zxvf server-jre-7u80-lin ...
- js弹出公告
调用: $(document).ready(function(){ sAlert("公告","内容"); }); 方法 function sAlert(strT ...
- CreateFile() 打开u盘 物理设备
//以下是用的vs2010 windows7 64 管理员权限编译成功的 HANDLE hDev = CreateFile(TEXT("\\\\.\\PhysicalDrive1" ...
- c#下载共享文件夹下的文件并记录错误日志
public void Run() { //获取目标文件列表 string _ErrorMessage = ""; string _ErrorMessageFile = " ...
- 使用gulp添加版本号
由于js和css的缓存问题,所以,希望在html上给js和css添加上版本号. 常见的用法是使用gulp-rev和gulp-rev-collector进行操作.使用这两个插件,得到的效果如下图所示: ...
- Java:switch语句例子
1.输入一个名次,第1-4名,分别称为冠军.亚军.季军.殿军,5名及5名以上,称为其他名次. import java.util.Scanner; public class switch1 { publ ...
- angular中的 ng-change
<!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...
- vim指令常用
慢慢尝试使用vim,不断学习使用新的快捷键,将常用快捷键但经常容易忘的写下来, 1. 复制黏贴 命令行模式下按住v选中,y表示复制,d表示剪切,p为复制.
- ElasticSearch学习笔记-02集群相关操作_cat参数
_cat参数允许你查看集群的一些相关信息,如集群是否健康,有哪些节点,以及索引的情况等的. 检测集群是否健康 curl localhost:9200/_cat/health?v 说明: curl 是一 ...
- 编译器错误信息: CS0433: 类型“ASP.usercontrols_total_ascx”同时存在
“/”应用程序中的服务器错误. 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码. 编译器错误信息: CS0433: 类型“ASP.use ...