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 }

时间: 2024-10-03 00:30:46

Java-单例模式(singleton)-转载的相关文章

Java 设计模式 单例模式(Singleton) [ 转载 ]

Java 设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创建对象 第一种(懒汉,线程不安全): 1 public class Singleton { 2 private static Singleton instance; 3 private Singleton (){} 4 5 public static Singleton getInstan

Java单例模式(Singleton)以及实现《转载》

一. 什么是单例模式 因程序需要,有时我们只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计. 二. 单例模式的特点 1. 单例模式只能有一个实例. 2. 单例类必须创建自己的唯一实例. 3. 单例类必须向其他对象提供这一实例. 三. 单例模式VS静态类 在知道了什么是单例模式后,我想你一定会想到静态类,"既然只使用一个对象,为何不干脆使用静态类?",这里我会将单例模式和静态类进行一个比较. 1. 单例可以继承和被继承,方法可以被override,而静态方

java设计模式之单例模式(Singleton)

Java设计模式之单例模式 单例模式是什么? 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式如何来设计呢? 保证一个类只能有一个实例,那么我们不能无限制的new 来创建,因为我们知道,new一次就是一个新的对象,那么构造器只能私有化private -- 构造器私有化 构造器私有化了,问题又出现了,构造器私有化了,那么我们怎么来创建唯一的对象呢?-- 提供一个公有的方法/提供一个公有的静态属性 再分析一下,公有方法, 实例方法还是类方法呢?--公有的类方法(获取类实例) 依据以上

Java单例模式的七种写法

Java单例模式的七种写法 第一种(懒汉,线程不安全) public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } 优缺点:这种写法lazy loading很明显,

【白话设计模式四】单例模式(Singleton)

转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二]外观模式(Facade) [白话设计模式三]适配器模式(Adapter) [白话设计模式四]单例模式(Singleton) [白话设计模式五]工厂方法模式(Factory Method) [白话设计模式六]抽象工厂模式(Abstract Factory) [白话设计模式七]策

单例模式 (Singleton pattern)

What is Singleton pattern? In Wikipedia, there is an explanation:"In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object." 一.什么是单例模式? 在维基百科中,是这样解释的,“在软件工程中,单例模式指的是对类加以限制,只允许创建

Java 单例模式探讨

以下是我再次研究单例(Java 单例模式缺点)时在网上收集的资料,相信你们看完就对单例完全掌握了 Java单例模式应该是看起来以及用起来简单的一种设计模式,但是就实现方式以及原理来说,也并不浅显哦. 总结一下我所知道的单例模式实现方式: 1.预先加载法 Java代码 class S1 { private S1() { System.out.println("ok1"); } private static S1 instance = new S1(); public static S1

【转】10个关于java单例模式的面试问题

10 interview question on Singleton Pattern in Java Question starts with What is Singleton class? Have you used Singleton before? Singleton is a class which has only one instance in whole application and provides a getInstance() method to access the s

Android - 单例模式(singleton)的使用

单例模式(singleton)的使用 本文地址:http://blog.csdn.net/caroline_wendy 单例(singleton)是特殊的Java类,在创建实例时,一个类仅允许创建一个实例. 应用能够在内存里存多久,单例就能存在多久,因此将对象列表保存在单例里可保持crime数据的一直存在, 不管activity.fragment及它们的生命周期发生什么变化. 要创建单例,需创建一个带有私有构造方法及get()方法类,其中get()方法返回实例. 如实例已存在,get()方法则直

你所知道的Java单例模式并不是单例模式

当我们搜索单例模式的时候,能看到很多例子,什么懒汉式.饿汉式,大概如下: public class Singleton { private static Singleton instance=null; private Singleton(){ System.out.println("Singleton..init..."); } public static Singleton getInstance(){ if(instance==null){ instance=new Single