java设计模式-----Singleton Pattern(单例模式)

本文详细解析了Singleton模式的实现原理及其在实际编程中的应用,包括使用静态方法、静态变量和注册器机制创建单例。通过具体示例,展示了如何确保对象的唯一性和高效管理资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Singleton 是一种创建性模型,它用来确保只产生一个实例,并提供一个访问它的全局访问点。 

  为了实现 Singleton 模式,我们需要一个静态的变量,能够在不创建对象的情况下记忆是否已经产生过实例了。静态变量或静态方法都可以在不产生具体实例的情况下直接调用,这样的变量或方法不会因为类的实例化而有所改变。 
  实现 Singleton 模式的办法通常有三种: 
  1.用静态方法实现 Singleton; 
  2.以静态变量为标志实现 Singleton; 
  3.用注册器机制来创建 Singleton。 
  对于上面3种方法,我觉得第一种很好用,写的连接池用了第一种和第三种方法。用第一种方法使得怎么取都是那一个连接池,用第三种方法使得只存在那一个连接池。 
  第一种方法具体实现为: 
  声明构造函数为 private,防止通过除由我们提供的方法之外的任意方式来创建一个实例,如果不把构造函数声明为private,编译器就会自作聪明的自动同步一个默认的friendly构造器。下面是摘抄的一个例子: 
  public class Singleton 
  { 
  private static Singleton s; 
  private Singleton() 
  { 
  }; 
   
  public static Singleton getInstance() 
  { 
  if (s == null) 
  s = new Singleton(); 
  return s; 
  } 
  } 

  // 测试类 
  class singletonTest 
  { 
  public static void main(String[] args) 
  { 
  Singleton s1 = Singleton.getInstance(); 
  Singleton s2 = Singleton.getInstance(); 
  if (s1==s2) 
  System.out.println 
  ("s1 is the same instance with s2"); 
  else 
  System.out.println 
  ("s1 is not the same instance with s2"); 
  } 
  } 
   
  singletonTest运行结果是: 
   
  s1 is the same instance with s2 
   
  这证明我们只创建了一个实例,再怎么取都是那个实例,很简单也很实用。 

  对于第二种实现方法,在类中加入一个静态变量做为标志,每次都在构造函数里进行检察。 
  下面是我写的一个例子: 
  public class Singleton { 
   static boolean existInstance=false; 
   public Singleton() 
   { 
   if (existInstance) 
    { 
     System.out.println("Already exist instanse!"); 
    } 
    else 
    { 
     //........................... 
     System.out.println("Create an instanse!"); 
     existInstance=true; 
   } 
  } 
  } 
  测试类如下: 
  public class Test { 

   public static void main(String[] args) { 
   Singleton s1=new Singleton(); 
    Singleton s2=new Singleton();  
   } 
  } 
  结果为: 
  Create an instanse! 
  Already exist instanse! 
  第二次的时候检测到已经有实例,接下来要怎么做就看自己的了。 
  与第一种方法相比,第一种是随便你怎么弄,都是那个实例,第二种是只能在第一次生成一个实例,再往后就会报错了。 
  下面来看看第三种方法:用注册器机制来创建 Singleton。 
  这种方法首先要建立一个管理器,用集合中的Hashtable 和Enumeration来实现addItem(Object key, Object value),getItem(Object key),removeItem(Object key)等方法实现,将key和value一一关联起来,创建实例前首先用addItem方法进行注册,再用getItem方法获取实例。 
  Hashtable中的key是唯一的,从而保证创建的实例是唯一的,用注册器机制来创建 Singleton模式的好处是易于管理,可以同时控制多个不同类型的Singleton 实例。 
  现在,我把那个连接池的部分代码弄出来讲讲第三种方法: 
  首先,定义个静态的hashtable: 
  public static Hashtable pools=new Hashtable(); 
  当创建连接池成功的时候,把产生的连接池对象放入pools中: 
  DBConnectionPool pool=new DBConnectionPool(poolName, url, usr, pwd, max);(DBConnectionPool 是自定义的连接池对象) 
  pools.put(poolName, pool); 
  取连接的时候,用的是: 
  public Connection getConnection(String poolName) 
   { 
   DBConnectionPool pool=(DBConnectionPool)pools.get(poolName); 
    if(pool!=null) 
   { 
    return pool.getConnection(); 
    } 
    return null; 
   } 

  前面说了,hashtable中的key值是唯一的,这样,名字为poolName的连接池只能有一个。 


补充:

-------------------------

package json;
/*
 * 书写一个单例模式
 * 有两种写法,第一种 饿汉式(提前加载,就是说提前初始化实例)
 * 			第二种  懒汉式(延迟加载,就是说在调用时候加载实例)
 */
public class Singleton {
	/**
	 * 使用饿汉式
	 * 满足条件
	 * 一个私有静态实例
	 * 一个私有构造函数
	 * 一个共有静态访问的实例函数
	 */
	String m ;
	/*
	private static Singleton instance = new Singleton();
	private Singleton(){
		//书写要加载的数据
			 int i = 5;
			 for(int j = 0;j<i;j++){
				m =  "test final class"+j;
				System.out.println(m);
			  }
	}
	public static Singleton getInstance(){
		return instance;
	}
	*/
	/**
	 * 使用懒汉式加载
	 * 满足条件
	 * 一个私有构造函数
	 *一个空的私有静态实例变量 
	 *一个共有静态同步实例方法
	 */
	
	private Singleton(){
		//书写自己的加载数据
		 int i = 5;
		 for(int j = 0;j<i;j++){
			m =  "test final class"+j;
			System.out.println(m);
		  }
	}
	private static Singleton instance = null;
	public static synchronized Singleton getInstance(){
		if(instance == null){
			instance = new Singleton();
		}
		return instance;
	}
	public void test2(){
		System.out.println(m);
	}
	public static void main(String args[]){
		//boolean  s = Singleton.getInstance().test();
		Singleton.getInstance().test2();
	}
}

 比较:
  饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变
  懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的
  推荐使用第一种 


转载于:https://my.oschina.net/xiahuawuyu/blog/70017

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值