您的位置:首页 > 职场人生

黑马程序员_JAVA设计模式之单例模式

2012-09-15 23:58 253 查看
------- android培训java培训、期待与您交流! ----------

 

JAVA标准的设计模式里面包含了23个,单例模式是最经典的设计模式了,每个人学习JAVA设计模式,都以这个模式作为入门。JAVA是一门优雅的语言,其中设计模式是最能说明这个的了,JAVA设计模式不仅仅是模式了,更是一种思想,不多说废话。

       单例模式的本质是:控制实例的个数。

       单例模式分饿汉式和懒汉式两种。

       饿汉式示例代码如下:

public class SingleCloud{
private int a ;
private String str;
private SingleCloud(){}   //似有化构造方法,不能让外界new出实例
private static  SingleCloud  instance = new SingleCloud();    //一定要静态的,这样类在加载的时候就创造实例
public static SingleCloud getInstance(){//当然获得实例的方法也是静态的,因为外界要访问非静态方法
return instance ;//构造方法我们使其私有,不能外界new的,因此这个方法必须静态,外界用类名就可访问,当然实例是类加载的时候就new出来了
}
public void f1(){
//TODO
}
public String f2(){
//TODO
}
}

 

懒汉式示例代码如下:

public class SingleCloud{
private int a ;
private String str;
private SingleCloud(){}
private static SingleCloud instance = null;   //在类加载的时候先不要创建实例
public SingleCloud getInstance(){  //用到实例的时候再来创建实例
if (null == instance){    //先判断是不是已经创建过了
instance = new SingleCloud();  //如果没有创建,那就进来创建实例
}
return instance ;
}
public void f1(){
//TODO
}
public String f2(){
//TODO
}
}

饿汉式和懒汉式都有其好处和缺点,饿汉式是不管你用不用我都在类加载的时候创建实例,可能程序运行很久才用得到,当用到的时候直接获取就行了,这样就浪费了空间。而懒汉式,用到的时候才去创建实例,典型的以时间换空间。两者还有区别就是,饿汉式是线程安全的,而懒汉式是线程不安全的,解决方式如下:

public class SingleCloud{
private int a ;
private String str;
private SingleCloud(){}
private static SingleCloud instance = null;   //在类加载的时候先不要创建实例*/

public SingleCloud getInstance(){
if (null == instance){
synchronized(SingleCloud.class){//进行同步,拿到的是类的同步监视器
if (null == instance){
instance = new SinlgeCloud();
}
}
}
return instance;
}

public void f1(){
//TODO
}

public String f2(){
//TODO
}
}

还有一种方案可以延迟加载而又保证线程安全,就是采用类级内部类,其实就是静态的内部类,这种类是不与外部类的实例绑定的,所以外部类在加载的时候并不会去初始化这种内部类,而在使用到的时候才进行初始化,示例代码如下:

public class SingleCloud{
private SingleCloud(){}
public SingleCloud getInstance(){
return SingleTonHolder.instance;
}
private static class SingleTonHolder{
public static  SingleCloud  instance = new SingleCloud();
}
}

其实最完美的单例是枚举类型,其实枚举的一个元素就是一个对象实例,枚举是一种特殊的类,首先它是类,也有属性也有方法,第二它是不能new出来的,它隐含的构造方法是私有的。

enum Grade{
A(345,23,"xiaoming);//这里只能有一个元素

private int score;

private int age;
private String name;

private Grade(int score,int age,String name){//
this.score = score;
this.name = name;
this.age = age;
}
public String toString(){
return "score=="+score+",name=="+name+",age=="+age;
}
}

后要说明的是,单例是在多大的范围内呢。很多人认为一台机器范围内,这是不正确的,应该是JVM范围内的单例,一个JVM可以运行多线程,一个JVM中的各个线程拿到的单例是同一个,如果一台机器上起了2个JVM,那么这个单例在同一个机器上就有两个实例了。

 

------- android培训java培训、期待与您交流! ----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息