java设计模式学习-单例模式
java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”单例模式可以保证一个应用中有且只有一个实例,避免了资源的浪费和多个实例多次调用导致出错。
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
所以相应的,我们用代码实现为:
1.私有化该类的构造函数
2.通过new在本类中创建一个本类对象
3.提供一个共有的方法,给给类创建的对象返回
1. 饿汉式写法
public class Singleton { //饿汉式
int a=1;
private Singleton(){};
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
调用方法:Singleton instance = Singleton.getInstance();
优点:饿汉式写法能保证线程安全,而且实现简单
缺点:在类加载的时候就完成了实例化,会造成内存浪费(可以忽略不计)
2.懒汉式(线程不安全,不可用)
public class Singleton { private static Singleton instance=null; private Singleton() {}; public static Singleton getInstance(){ if(instance==null){
instance=new Singleton();
}
return instance;
}
}
因为只有在调用getInstance()这个方法的时候,才会去初始化这个单例,所以称为懒汉式
懒汉式存在线程安全问题,当2个或多个线程同时调用getInstance()方法时,有可能发生如下情况:当第一个线程在执行 if(instance==null)判断的时候,因为此时instance为空,他将会执行instance=new Singleton()来实例化对象,而第二个进程也同时进入了 if(instance==null)的判断,他可能会在第一个线程没有实例化之前进行判断,此时instance依旧为空,于是就实例化了2个Singleton对象,违背了单例模式。
于是,就有了懒汉式的双重校验锁
即加锁并且2次判断instance是否为空
public class Singleton2 {//懒汉式双重校检
private static Singleton2 instance = null;
private Singleton2(){}; public static Singleton2 getInstance() {
if(instance ==null) {
synchronized (Singleton2.class) {
if(instance == null){
instance = new Singleton2();
} }
}
2次if(instance == null)校验,确保了线程安全,延迟加载,效率较高
懒汉式双重校验完整例子:
public class Singleton_test {
private int a =1; private static Singleton_test singleton_test =null; private Singleton_test(){}; public static Singleton_test getInstance(){//懒汉式双重校验锁
if(singleton_test ==null){
synchronized (Singleton2.class) {
if(singleton_test ==null){
singleton_test =new Singleton_test();
} }
}
return singleton_test; } public int getA() {
return a;
} public void setA(int a) {
this.a = a;
}
public void printInfo() {
System.out.println("number" + a);
} }
Singleton_test
public class Main_test {
public static void main(String[] args){
Singleton_test singleton_test = Singleton_test.getInstance();
singleton_test.setA(2); Singleton_test singleton_test2 = Singleton_test.getInstance();
singleton_test2.setA(3); singleton_test.printInfo();
singleton_test2.printInfo(); if(singleton_test == singleton_test2){
System.out.println("创建的是同一个实例");
}else{
System.out.println("创建的不是同一个实例");
} }
}
Main_test
内部类
public class Singleton{ private Singleton() {}; private static class SingletonHolder{
private static Singleton instance=new Singleton();
} public static Singleton getInstance(){
return SingletonHolder.instance;
}
}
和饿汉式类似,但又有不同。两者都是采用了类装载的机制来保证初始化实例时只有一个线程。不同
的地方在饿汉式方式是只要Singleton类被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时
并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonHolder类,从而完成Singleton的实例化。
类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是
无法进入的。
优点:避免了线程不安全,延迟加载,效率高。
最新文章
- LINQ LINQ Operators and Lambda Expression - Syntax &; Examples
- MongoDB 3.0 用户创建
- (四)Ubuntu 14.04 文件服务器--samba的安装和配置
- Js判断一个单词是否有重复字母
- jquery获取元素索引值index()方法
- hadoop笔记之Hive的数据存储(桶表)
- MVC 过滤器1
- 【Tomcat】Tomcat配置之请求字符串编码
- Parade
- HTML style基础2
- 他山之石,calling by share——python中既不是传址也不是传值
- 计算价格, java中浮点数精度丢失的解决方案
- python中的清屏函数
- Oracle相关安装经验总结
- swift 8.0之后打开 手机设置
- HDU 4791 Alice's Print Service 思路,dp 难度:2
- 有序列表ol和定义列表dl,dt,dd
- bzoj4753: [Jsoi2016]最佳团体(分数规划+树形依赖背包)
- RequestMaping url带参数及参数带“.";的解决办法
- ubuntu 14.04 解决apt-get update报错
热门文章
- 浅学CLR via C#笔记之类型转换
- .net SHA-256 SHA-1
- Action请求后台出现Response already commited异常解决方法
- 你听过稀疏数组(sparseArray)吗?
- mybatisplus 使用案例
- sql sever2008 R2 检测到索引可能已损坏。请运行 DBCC CHECKDB。
- 微信小程序 之wxml保留小数点后两位数的方法及转化为字符串的方法
- git命令——git commit
- 基于numpy实现矩阵计算器
- Mybatis3.0-[tp_28-29]-映射文件-resultMap_自定义结果集映射规则_及关联环境的搭建