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帮助我们保证了线程的安全性,在类进行初始化时,别的线程是

无法进入的。

优点:避免了线程不安全,延迟加载,效率高。

 
参考博客:

http://blog.csdn.net/dmk877/article/details/50311791

												

最新文章

  1. LINQ LINQ Operators and Lambda Expression - Syntax & Examples
  2. MongoDB 3.0 用户创建
  3. (四)Ubuntu 14.04 文件服务器--samba的安装和配置
  4. Js判断一个单词是否有重复字母
  5. jquery获取元素索引值index()方法
  6. hadoop笔记之Hive的数据存储(桶表)
  7. MVC 过滤器1
  8. 【Tomcat】Tomcat配置之请求字符串编码
  9. Parade
  10. HTML style基础2
  11. 他山之石,calling by share——python中既不是传址也不是传值
  12. 计算价格, java中浮点数精度丢失的解决方案
  13. python中的清屏函数
  14. Oracle相关安装经验总结
  15. swift 8.0之后打开 手机设置
  16. HDU 4791 Alice's Print Service 思路,dp 难度:2
  17. 有序列表ol和定义列表dl,dt,dd
  18. bzoj4753: [Jsoi2016]最佳团体(分数规划+树形依赖背包)
  19. RequestMaping url带参数及参数带“."的解决办法
  20. ubuntu 14.04 解决apt-get update报错

热门文章

  1. 浅学CLR via C#笔记之类型转换
  2. .net SHA-256 SHA-1
  3. Action请求后台出现Response already commited异常解决方法
  4. 你听过稀疏数组(sparseArray)吗?
  5. mybatisplus 使用案例
  6. sql sever2008 R2 检测到索引可能已损坏。请运行 DBCC CHECKDB。
  7. 微信小程序 之wxml保留小数点后两位数的方法及转化为字符串的方法
  8. git命令——git commit
  9. 基于numpy实现矩阵计算器
  10. Mybatis3.0-[tp_28-29]-映射文件-resultMap_自定义结果集映射规则_及关联环境的搭建