黑马程序员技术交流社区

标题: 单例设计模式 [打印本页]

作者: ↑↓ME→←    时间: 2014-1-12 09:44
标题: 单例设计模式
  1. public class Danli{
  2. /*
  3.         private Danli(){}
  4.        
  5.         private static Danli danli;
  6.        
  7.         public static Danli getInstance(){
  8.                 if(danli == null){
  9.                         danli = new Danli();
  10.                 }
  11.                 return danli;
  12.         }  */
  13.        
  14.         private Danli(){}
  15.        
  16.         private static Danli danli = new Danli();
  17.        
  18.         public static Danli getInstance(){
  19.                 return danli;
  20.         }
  21. }
复制代码

对这个概念有点模糊,哪位大神肯解释一下乎!
作者: xu6148152    时间: 2014-1-12 09:55
本帖最后由 xu6148152 于 2014-1-12 10:00 编辑

也就是构造函数为private.
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。

Danli的类通过将构造方法限定为private避免了类在外部被实例化,
在同一个虚拟机范围内,Danli的唯一实例只能通过getInstance()访问。



作者: 汪伟楠    时间: 2014-1-12 10:05
单例设计模式
1.设计模式:解决某一类问题最行之有效的方法。
2.单例设计模式:解决一个类在内存只存在一个对象。
3.想要保证对象唯一。
(1)为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
(2)还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
(3)为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
4.这三步怎么用代码体现呢?
(1)将构造函数私有化。
(2)在类中创建一个本类对象。
(3)提供一个方法可以获取到该对象。
记录原则:定义单例设计模式,建议使用饿汉式。

饿汉式
先初始化对象。称为:饿汉式。
Single类一进内存,就已经创建好了对象。
class Single
{
        private static Single s = new Single();
        private Single(){}
        public static Single getInstance()
        {
                return s;
        }
}
懒汉式
对象是方法被调用时,才初始化,也叫做对象的延时加载。成为:懒汉式。
Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。
1.特点:实例的延时加载
2.是否有安全问题?
有,如果多线程访问时会出现安全问题。
解决:可以加同步来解决,而加同步的方式用同步代码块和同步函数都行,但是稍微低效。 用双重判断的形势能解决效率的问题。
3.加同步的时候使用的锁是哪一个?
该类所属的字节码文件对象。
class Single
{
        private static Single s = null;
        private Single(){}
        public static Single getInstance()
        {
                if(s==null)
                {
                        synchronized(Single.class)
                        {                               
                                if(s==null)
                                        s = new Single();
                        }
                }
                return s;
        }
}

作者: /yhh大雁/zhh    时间: 2014-1-12 10:15
顶2楼的解释,和毕老师说的一模一样
作者: 淡夜清风    时间: 2014-1-12 10:20
毕老师的java基础视频上有啊。。讲的很详细,很好。你看看就懂了。

黑马程序员_毕向东_Java基础视频教程第06天-09-面向对象(单例设计模式)
下载地址:http://dl.dbank.com/c0g0l3zr6g
作者: 高丽华    时间: 2014-1-12 10:47
这是我关于单例设计模式的总结,希望能对你有用:
设计模式---解决某一类问题最行之有效的方法。
单例设计模式----解决一个类在内存只存在一个对象,想要保证对象唯一。
Runtime()方法就是单例设计模式进行设计的。
如何保证对象唯一性呢?
思想:
1,不让其他程序创建该类对象.
2,在本类中创建一个本类对象。
3,对外提供方法,让其他程序获取这个对象。
步骤:
1,因为创建对象都需要构造函数初始化,只要将本类中的构造函数私有化,其他程序就无法再创建该类对象;
2,就在类中创建一个本类的对象;
3,定义一个方法,返回该对象,让其他程序可以通过方法就得到本类对象。
代码体现:
1,私有化构造函数;
2,创建私有并静态的本类对象;
3,提供一个方法可以获取到该对象。
饿汉式
class student {
        private student(){}// //私有化构造函数。
        private static student s=new student();//创建私有并静态的本类对象。
        public static student getstudent(){//提供一个方法获取该对象
                return s;
        }
  }
懒汉式:延时加载

class student {
        private student(){}
        private static student s=null;
        public static student getstudent(){
                if(s==null){
                        s=new student();
                }
                return s;
        }
}
懒汉式和饿汉式的不同之处是:懒汉式的特点是延时加载;
懒汉式延时加载有问题,如果多线程访问时会出现安全问题;
解决安全问题的方法是:可以加同步来解决,而同步的方式有加同步代码块和同步函数,但是效率有些低,所以用双重判断的形式能解决效率问题。
用同步代码块解决如下:

  class student {
        private student(){}
        private static student s=null;
        public static synchronized student getstudent(){
                if(s==null){
                        s=new student();
                }
                return s;
        }
}
用双重判断解决如下
  
class student {
        private student(){}
        private static student s=null;
        public static  student getstudent(){
                if(s==null){
                        synchronized(student.class){
                                if(s==null)
                                        s=new student();
                        }
                }
                return s;
        }
}
在一般的情况下,定义单例的时候,使用饿汉式。

作者: app297    时间: 2014-1-12 17:04
  1. public class Test {
  2.         public static void main(String[] args) {
  3.                 Danli a = Danli.getInstance();
  4.                 Danli b = Danli.getInstance();
  5.                 Danli c = Danli.getInstance();
  6.                 Danli d = Danli.getInstance();
  7.                 System.out.println(a + "," + b + "," + c);
  8.                 //由这里的打印结果也可以看出来都是指向的是一个内存地址
  9.                 //org.zq.test.Danli@527c6768,org.zq.test.Danli@527c6768,org.zq.test.Danli@527c6768
  10.         }
  11. }

  12. class Danli{
  13. /*
  14.         private Danli(){}
  15.         
  16.         private static Danli danli;
  17.         
  18.         public static Danli getInstance(){
  19.                 if(danli == null){
  20.                         danli = new Danli();
  21.                 }
  22.                 return danli;
  23.         }  */
  24.         
  25.         private Danli(){}  //私有构造函数,外部就不能直接访问,
  26.         
  27.         private static Danli danli = new Danli();
  28.         //用static 表示该对象存在与内存中的未实例化之前就存在了,并且也私有化了,外部不能直接访问
  29.         public static Danli getInstance(){
  30.                 return danli;  //这里提供一个访问方法,返回的是成员变量,并且是共享数据
  31.                 //由于private static Danli danli = new Danli();  
  32.                 //danli 已经在内存中存在,且是该类的成员属性,再次创建对象获取的时候也是这个数据共享区中的对象
  33.                 //就保证了,这个对象只能存在一个,。
  34.                
  35.         }
  36. }
复制代码






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2