黑马程序员技术交流社区

标题: 关于单例的疑问 [打印本页]

作者: 陈山    时间: 2012-11-6 12:46
标题: 关于单例的疑问
本帖最后由 陈山 于 2012-11-20 22:26 编辑

用单例模式有什么好处?一般在什么情况下使用单例设计模式?
作者: 葬天    时间: 2012-11-6 13:05
单例 就像 它的名字一样
当需要 类只存在一个实例时,就用单例模式


作者: 马纵驰    时间: 2012-11-6 13:12
设计模式:是解决某一问题最有效的方法。
而单例设计模式是实现一个类在内存中只有一个对象的模式
作者: 李计伟    时间: 2012-11-6 13:19
本帖最后由 李计伟 于 2012-11-6 13:24 编辑

单例模式是一种常见的设计模式。单例可以节省内存空间只有一个实例可以直接类名访问它。比如有很多对象要访问一个数据没有必要都来访问数据库。只需访问一个实例然后通过它来访问数据库即可。再比房子里安装空调没有必要为每一个人安一个,安一个即可大家都能共享到,如在多线程时要加同步。
作者: 徐强    时间: 2012-11-6 13:20
首先,单例模式是对象的创建模式之一,此外还包括工厂模式。单例模式的三个特点:
1,该类只有一个实例
2,该类自行创建该实例(在该类内部创建自身的实例对象)
3,向整个系统公开这个实例接口
  1. class Singleton {
  2.      
  3.     //私有,静态的类自身实例
  4.     private static Singleton instance = new Singleton();
  5.      
  6.     //私有的构造子(构造器,构造函数,构造方法)
  7.     private Singleton(){}
  8.      
  9.     //公开,静态的工厂方法
  10.     public static Singleton getInstance() {
  11.         return instance;
  12.     }
  13. }
复制代码
使用单例模式,保证一个类只有一个实例对象,这样就可以节约内存;当然这不是主要原因,主要是应为当一个类的实例存在多个会引起程序逻辑错误的时候,就必须使用单例模式。比如类似有序的号码生成器这样的东西,怎么可以允许一个应用上存在多个呢?

作者: 奋斗的青春    时间: 2012-11-6 13:21
本帖最后由 吴愿涛 于 2012-11-6 13:23 编辑

java模式之单例模式:
          单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。
特点:
       1,一个类只能有一个实例
       2,自己创建这个实例
       3,整个系统都要使用这个实例

Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例在。 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回(garbage collection)。

    例: 在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。
    Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。一些资源管理器常常设计成单例模式。
    外部资源:譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口被两个请求同时调用。内部资源,譬如,大多数的软件都有一个(甚至多个)属性文件存放系统配置。这样的系统应当由一个对象来管理这些属性文件。

一个例子:Windows 回收站。
在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且回收站自行提供自己的实例。因此,回收站是单例模式的应用。

两种形式:
1,饿汉式单例类
public class Singleton {
  private Singleton(){}
  //在自己内部定义自己一个实例,是不是很奇怪?
  //注意这是private 只供内部调用
  private static Singleton instance = new Singleton();
  //这里提供了一个供外部访问本class的静态方法,可以直接访问  
  public static Singleton getInstance() {
    return instance;   
   }
}

作者: 李长波    时间: 2012-11-11 22:54
优点:
第一、控制资源的使用,通过线程同步来控制资源的并发访问;
第二、控制实例产生的数量,达到节约资源的目的。
第三、作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信。
用的地方我知道的:
数据库连接池的设计一般采用单例模式,数据库连接是一种数据库资源。
Struts、Spring框架都用了单例模式


作者: 廖力    时间: 2012-11-11 23:07
  1. // 饿汉式
  2. class HungrySingleton {
  3.         private static HungrySingleton instance = new HungrySingleton();

  4.         private HungrySingleton() {
  5.         }

  6.         static HungrySingleton getInstance() {
  7.                 return instance;
  8.         }
  9. }

  10. // 懒汉式
  11. class LazySingleton {
  12.         private static LazySingleton instance = null;

  13.         private LazySingleton() {
  14.         }

  15.         static LazySingleton getInstance() {
  16.                 if (instance == null) instance = new LazySingleton();
  17.                 return instance;
  18.         }
  19. }
复制代码
只说2点
1单例模式分饿汉式和懒汉式 区别就在与懒汉式是在第一次获取单例对象时才创建对象
2单例在多线程中很有用 比如多个线程要使用、操作同一个对象 但是注意加锁

其它的楼上都说得差不多了
作者: 深井看海    时间: 2012-11-11 23:17
单例设计模式:解决一个类在内存中只存在一个对象
单例设计模式有两种模式:饿汉式和懒汉式
单例想要保证对象唯一:
1.        为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象
2.        还为了让其他程序可以访问到该类对象,只好在本类中自定义一个对象
3.        为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式


作者: 李涛兴    时间: 2012-11-12 22:38
单例模式是用来解决一个类在内存中只存在一个对象的问题,其中有两种方法,楼上的同学也给出了代码,我就说说代码实现的过程吧;
1,将构造函数私有化。
2,在类中创建一个本类对象。
3,提供一个方法获取该对象。
饿汉式与懒汉式的区别在于,前者先初始化,后者在被调用时再初始化。
一般建议使用饿汉式,因为懒汉式不利于代码的阅读性,因为还要对对象进行判断。
作者: 一身顺利    时间: 2012-11-13 12:02
适用性:
1.当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2.当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

public class Singleton {
   
    private static Singleton sing;

    private Singleton() {
        
    }
   
    public static Singleton getInstance() {
        if (sing == null) {
            sing = new Singleton();
        }
        return sing;
    }
}

public class Test {
   
    public static void main(String[] args) {
        Singleton sing = Singleton.getInstance();
        Singleton sing2 = Singleton.getInstance();
        
        System.out.println(sing);
        System.out.println(sing2);
    }
}

//singleton.Singleton@1c78e57
//singleton.Singleton@1c78e57
                       




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