A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

设计模式:就是解决问题的方法;
单例设计模式:
解决的问题:保证类中的对象的唯一性;
如何保证对象唯一性:
1:不允许其他程序用new创建该类对象;
2:在该类创建一个该类的实例;
3:对外提供一个返回实例的方法(让别人 能够得到实例)
步奏:
1私有化该类的构造函数;
2通过new在本类中创建一个本类对象;
3定义一个公有的函数(方法),返回该类的对象;
package prooject;
class Test1
{
        private int num;
     private static Test1 s=new Test1();
     public  void setNum(int num)
     {
             this.num=num;
     }
     public  int  getNum()
     {
             return num;
     }
        private Test1 ()       
        {
       
        }
        public static Test1 getInstance()
        {
                return s;
        }
}
public class Test
{public static void main(String[] args)
{
        Test1 s1=Test1.getInstance();
        Test1 s2=Test1.getInstance();
        System.out.println(s1==s2);
        s1.setNum(10);
        s2.setNum(20);
        System.out.println("s1="+s1.getNum());
        System.out.println("s2="+s2.getNum());
       
}
               
}

5 个回复

倒序浏览
本帖最后由 MissMr. 于 2015-6-3 22:19 编辑

一般来说,单例模式有五种写法:懒汉、饿汉、双重检验锁、静态内部类、枚举。
就我个人而言,一般情况下直接使用饿汉式就好了,如果明确要求要懒加载(lazy initialization)会倾向于使用静态内部类,如果涉及到反序列化创建对象时会试着使用枚举的方式来实现单例。
1,饿汉式 static final field
这种方法非常简单,因为单例的实例被声明成 static 和 final 变量了,在第一次加载类到内存中时就会初始化,所以创建实例本身是线程安全的。
public class Singleton{
    //类加载时就初始化
    private static final Singleton instance = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
}
这种写法如果完美的话,就没必要在啰嗦那么多双检锁的问题了。缺点是它不是一种懒加载模式(lazy initialization),单例会在加载类后一开始就被初始化,即使客户端没有调用 getInstance()方法。饿汉式的创建方式在一些场景中将无法使用:譬如 Singleton 实例的创建是依赖参数或者配置文件的,在 getInstance() 之前必须调用某个方法设置参数给它,那样这种单例写法就无法使用了。

2,静态内部类 static nested class
我比较倾向于使用静态内部类的方法,这种方法也是《Effective Java》上所推荐的。
public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;
    }  
}
这种写法仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,因此它是懒汉式的;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖 JDK 版本。

评分

参与人数 1技术分 +1 收起 理由
lwj123 + 1

查看全部评分

回复 使用道具 举报
一般来说,单例模式有五种写法:懒汉、饿汉、双重检验锁、静态内部类、枚举。
就我个人而言,一般情况下直接使用饿汉式就好了,如果明确要求要懒加载(lazy initialization)会倾向于使用静态内部类,如果涉及到反序列化创建对象时会试着使用枚举的方式来实现单例。
1,饿汉式 static final field
这种方法非常简单,因为单例的实例被声明成 static 和 final 变量了,在第一次加载类到内存中时就会初始化,所以创建实例本身是线程安全的。
public class Singleton{
    //类加载时就初始化
    private static final Singleton instance = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return instance;
    }
}
这种写法如果完美的话,就没必要在啰嗦那么多双检锁的问题了。缺点是它不是一种懒加载模式(lazy initialization),单例会在加载类后一开始就被初始化,即使客户端没有调用 getInstance()方法。饿汉式的创建方式在一些场景中将无法使用:譬如 Singleton 实例的创建是依赖参数或者配置文件的,在 getInstance() 之前必须调用某个方法设置参数给它,那样这种单例写法就无法使用了。
2,静态内部类 static nested class
我比较倾向于使用静态内部类的方法,这种方法也是《Effective Java》上所推荐的。
public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;
    }  
}
这种写法仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,因此它是懒汉式的;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖 JDK 版本。
回复 使用道具 举报
服务器太卡了,发重复了
回复 使用道具 举报
谢啦,帮我补充这么多足
回复 使用道具 举报
好全面,我惭愧,你们认识的这么全
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马