- 浏览: 236037 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (101)
- js (10)
- java (39)
- HTTP请求:GET与POST方法的区别(转) (1)
- Freemarker 语法规则 (1)
- AJAX级联菜单实例 (1)
- oralce (1)
- myeclipse (5)
- struts (12)
- sql存储过程基础(转) (4)
- JBPM (1)
- mysql (4)
- hibernate (3)
- ibatis (4)
- spring (4)
- 计算机技术 (1)
- nosql (1)
- sqlserver (1)
- servlet (1)
- 拦截器 (1)
- andriod 开发 (1)
- 程序员 (0)
- 多线程 (2)
- Jenkins (1)
- zk (1)
- JPA (2)
最新评论
-
zhangzh888:
怎么下载 啊 都没有看见文件
sftp处理文件 -
wx_hello:
怎么得到文件的属性呢? 比如文件的新建时间
sftp处理文件 -
HappyVeryGood:
“运行时异常(即非受控异常)自动强制执行整个逻辑工作单元的回滚 ...
事物管理,spring事物详解,spring @transactional -
skeely1234:
感谢分享,太帅了
eclipse下修改项目名导致tomcat内发布名不一致的解决方法
概念:
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 //饿汉式单例类.在类初始化时,已经自行实例化
(特性:1. 每次装载都需要消耗内存空间
2.以空间换取时间的
3.线程是安全的
)
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 //懒汉式单例类.在第一次调用的时候实例化
(特性:1.第一次装载都需要消耗内存空间 后面不需要实例化类
2. 以时间换空间的设计
3 在多线程的时候会产生多个实例,这样就不安全的)
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中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式有一下特点:
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 //饿汉式单例类.在类初始化时,已经自行实例化
(特性:1. 每次装载都需要消耗内存空间
2.以空间换取时间的
3.线程是安全的
)
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 //懒汉式单例类.在第一次调用的时候实例化
(特性:1.第一次装载都需要消耗内存空间 后面不需要实例化类
2. 以时间换空间的设计
3 在多线程的时候会产生多个实例,这样就不安全的)
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 }
发表评论
-
习惯的开发错误
2014-09-09 17:25 414在一个包的下面 创建一个test.java 文件 这样一个小 ... -
得到指定年份的所有周末
2014-08-20 18:18 1171/** * 得到指定年份的所有周末 */ publi ... -
对对字符串可能出现报空指针的小问题
2014-04-14 14:42 850今天很是郁闷啊,遇到一个基础的问题比对字符串的两种写法: ... -
往文件里写入字符串
2014-01-20 13:52 1102package ab; import java.io.Bu ... -
Java数组,去掉重复值、增加、删除数组元素
2014-01-02 14:18 5142import java.util.List; import ... -
java定时器的使用(Timer)
2013-10-14 16:42 2415java定时器的使用(Timer) 2008-02-14 13 ... -
JSch - Java实现的SFTP(文件上传详解篇)(转)
2013-10-14 16:40 3411JSch是Java Secure Channel的缩写。JSc ... -
jvm
2013-09-30 15:03 746网上看到一位javaeye的同志写的文章,感觉总结的比较好,虽 ... -
sftp处理文件
2013-09-30 15:02 8032最近工作涉及sftp处理文件,写了个工具类,代码已经测试。请需 ... -
java BigDecimal的使用和四舍五入及格式规范(精准数据)
2013-06-17 15:37 21551• Java中的简单浮点数类型float和double不能够进 ... -
servlet拦截器代码
2013-03-29 13:45 22081- 实现Servlet.Filter接口 public cl ... -
session 超时的时间设置
2013-03-22 14:47 935为单个Web应用 配置超时时间可以在web.xml中使用< ... -
Calendar 获取日期
2013-01-23 10:44 1282Calendar 获取日期 如果想得到某个星期几是什么日期, ... -
JAVA帮助文档全系列
2013-01-05 11:02 0JAVA帮助文档全系列 JDK1.5 JDK1.6 JD ... -
Cannot create a server using the selected type
2012-08-27 11:02 0eclipse中安装tomcat服务器,报错" Ca ... -
线程池(jdk实现)
2012-07-10 15:01 0Sun在Java5中,对Java线程的类库做了大量的扩展,其中 ... -
遍历集合
2012-06-26 17:28 1042* * To change this template, c ... -
(转)Java 序列化
2012-06-26 14:55 1922当我们需要序列化一个J ... -
权限控制的发散性思维
2012-06-15 17:31 959权限控制的讨论 http://www.iteye.com ... -
(转载)Java设计模式的三大块讲解
2012-06-15 17:27 1169转载自http://www ...
相关推荐
java单例模式详解 简单代码实现2中单例模式 有详细的文字说明。
java单例模式详解Java系列2021.pdf
Java设计模式-单例模式详解
java设计模式之单例模式详解,包含例子,详解。
详解JAVA单例模式及多种实现
1、掌握单例模式的应用场景。 2、掌握 IDEA 环境下的多线程调试方式。 3、掌握保证线程安全的单例模式策略。 4、掌握反射暴力攻击单例解决方案及原理分析。 5、序列化破坏单例的原理及解决方案。 6、掌握常见的...
java 单例模式和工厂模式实例详解.docx
Java设计模式-单例模式详解,包含三种模式式:饿汉,懒汉,登记式,以及线程多同步的处理
主要介绍了9种Java单例模式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
【课堂笔记】单例模式详解
主要介绍了java 单例模式的实例详解的相关资料,希望通过本文能帮助大家彻底理解掌握这部分内容,需要的朋友可以参考下
主要介绍了Java 单例模式线程安全问题的相关资料,希望通过本文大家能了解掌握单例模式中线程安全的使用方法,需要的朋友可以参考下
单例设计模式: 1、构造函数私有 2、定义类型为本身类型的成员 3、类中提供一个公共的并且静态的获取本类实例的方法
在本篇文章里小编给大家整理的是关于Java单例模式的知识点详解,有兴趣的朋友们可以学习参考下。
java设计模式详解,内容包括java开发中常用的开发模式,例如单例模式以及相应的实现方法等,我找了好久,所以分稍微多点
今天小编就为大家分享一篇关于Java双重检查加锁单例模式的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
主要介绍了Java单例模式实现的几种方式的相关资料,需要的朋友可以参考下
本文实例讲述了JavaScript设计模式—单例模式.分享给大家供大家参考,具体如下: 单例模式也称为单体模式,其中: 1,单体模式用于创建命名空间,将系列关联的属性和方法组织成一个逻辑单元,减少全局变量。 逻辑...
主要介绍了Java设计模式编程中的单例模式和简单工厂模式以及实例,使用设计模式编写代码有利于团队协作时程序的维护,需要的朋友可以参考下