一、定义:保证某个类在实现的时候只能产生一个实例的模式
二、实现方法:有两种实现方法,懒汉式和饿汉式。
1、懒汉式实现方式
特点:在程序第一次调用getInstence的时候实现实例的产生
优点:只有在使用到这个类的时候才会去实例化,这样可以更好的节省内存资源
缺点:不是线程安全的,在多线程中可能会实例化不止一个。假设有两个线程A、B都要创建一个实例,A调用getInstance,
发现singleton是null,此时B线程获得CPU控制权,发现singleton也是空的,这样A和B就各自创建一个实例,(而且后面
创建的应该会把前面创建的覆盖)
public class Singleton1 {
public static Singleton1 singleton = null ;
public int index = 0 ;
public static Singleton1 getInstance() {
if(singleton == null){
singleton = new Singleton1();
}
return singleton ;
}
private Singleton1(){
}
public void setIndex(int i) {
this.index = i ;
}
public void test(String name) {
System.out.println("单例模式实例"+name+":"+index);
}
}
修改:对getInstance方法进行改进,加入线程锁
public class Singleton1 {
public static Singleton1 singleton = null ;
public int index = 0 ;
public static synchronized Singleton1 getInstance() {
if(singleton == null){
singleton = new Singleton1();
}
return singleton ;
}
private Singleton1(){
}
public void setIndex(int i) {
this.index = i ;
}
public void test(String name) {
System.out.println("单例模式实例"+name+":"+index);
}
}
2、饿汉式实现方式
优点:在程序初始化的时候就将类实例化,所以是线程安全的
缺点:如果这个类在以后用不着,那么就会造成内存资源的浪费
public class Singleton2 {
private int index = 0 ;
public static Singleton2 singleton = null ;
static{
singleton = new Singleton2();
}
public static Singleton2 getInstance() {
return singleton ;
}
private Singleton2(){
}
public void setIndex(int i) {
this.index = i ;
}
public void test(String name) {
System.out.println("单例模式实例"+name+":"+index);
}
}
三、拓展:控制实例限定个数的类
思路:利用一个私有的static int 变量来控制可以创建的实例数量
public class Singleton3 {
public static Map<String, Singleton3> map = new HashMap<String, Singleton3>();
private static int cancreate = 5 ;
public static synchronized Singleton3 getInstance(String name) {
if(!map.containsKey(name)&&cancreate!=0){
map.put(name, new Singleton3());
cancreate--;
}else if(cancreate == 0){
System.out.println(Singleton3.class.getName()+"可创建数量已达上限!");
return null ;
}
return map.get(name);
}
private Singleton3(){};
}
四、单例模式的优缺点
1、优点
1.1 在内存中只有一个实例,节省资源
1.2 可以在类中使用全局共享的变量或者资源(这个以前没看设计模式的时候其实就已经用了,在一个类里面只有全局共享的
static变量)
2、缺点
2.1 单例模式一般没有接口,所以要扩展就很难(给单例模式的类增加接口是没有意义的,因为加来加去也只能实例化一次,
那接口和类中自带的方法有什么区别呢?)
2.2 测试不方便(这个具体还不是很秦楚)
五、感想
以前从来没想过原来构造器前面可以加private来修饰,构造器前面的修饰符可以控制该类对于其它类的可见程度!