单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。对一些类来说,只有一个实例是很重要的,虽然系统中可以有许多打印机,但却只应该有一个打印机假脱机,只应该有一个文件系统和一个窗口管理器,一个数字滤波器只能有一个A/D转换器,一个会计系统只能专用于一个公司。怎样才能保证一个类只有一个实例并且这个实例易于被访问,一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象,一个更好的方法是让类自身负责保存他的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法,这就是Singleton模式。
模式的问题:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
解决方案:怎样才能保证一个类只有一个实例并且这个实例易于被访问,一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象,一个更好的方法是让类自身负责保存他的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法,这就是Singleton模式。
使用条件:
---当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
---当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
效果:单例模式有许多优点:
--对唯一实例的受控访问,
-- 缩小命名空间,
--允许对操作和表示的精化,
--允许可变数目的实例。
--比类操作更灵活。
简单事例:
例如:一个产生随机数的例子,整个应用程序中只需要一个类的实例来产生随机数,客户端程序从类中获取这个实例,调用这个实例的方法nextInt(),公用的方法访问需要进行同步,这是单例模式需要解决的同步问题。
![](http://img1.51cto.com/attachment/200709/200709231190542919218.gif)
package cn.com.singleton; import java.util.Random; public class Singleton { private Singleton(){ generator = new Random(); } public void setSeed(int seed){ generator.setSeed(seed); } public int nextInt(){ return generator.nextInt(); } public static synchronized Singleton getInstance(){ if (instance == null) { instance = new Singleton(); } return instance; } private Random generator; private static Singleton instance; }
客户端:
package cn.com.singleton; public class Client { public static void main(String[] args) { // TODO 自动生成的方法存根 Singleton s1 = Singleton.getInstance(); System.out.println(s1.toString()); for(int i=0;i<10;i++){ Singleton s2 = Singleton.getInstance(); System.out.println("The randomed number is "+s2.toString()); } } }
测试结果:
cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab
The randomed number is cn.com.singleton.Singleton@5e55ab