java单例模式中饿汉式与懒汉式

单例模式用途:

单例模式属于工厂模式的特例,只是它不需要输入参数并且始终返回同一对象的引用。

单例模式能够保证某一类型对象在系统中的唯一性,即某类在系统中只有一个实例。它的用途十分广泛,打个比方,我们开发了一个简单的留言板,用户的每一次留言都要将留言信息写入到数据库中,最直观的方法是没次写入都建立一个数据库的链接。这是个简单的方法,在不考虑并发的时候这也是个不错的选择。但实际上,一个网站是并发的,并且有可能是存在大量并发操作的。如果我们对每次写入都创建一个数据库连接,那么很容易的系统会出现瓶颈,系统的精力将会很多的放在维护链接上而非直接查询操作上。这显然是不可取的。

如果我们能够保证系统中自始至终只有唯一一个数据库连接对象,显然我们会节省很多内存开销和cpu利用率。这就是单例模式的用途。当然单例模式不仅仅只用于这样的情况。

在《设计模式:可复用面向对象软件的基础》一书中对单例模式的适用性有如下描述:

1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

2、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

 

下面对单例模式的饿汉式与懒汉式进行简单介绍:

1、饿汉式:在程序启动或单例模式类被加载的时候,单例模式实例就已经被创建。

2、懒汉式:当程序第一次访问单例模式实例时才进行创建。

如何选择:

如果单例模式实例在系统中经常被用到,饿汉式是一个不错的选择。

反之,如果很少被用到,那么懒汉式是一个不错的选择。

饿汉式:

设计思想:构造方法私有,这样就保证了在外部是无法实例化对象的;然后先在内部定义一个静态常量对象,再写一个static方法来返回这个对象,这样就保证是前后一个对象了。

代码实现

 

public class HungryManSingleton {
	/**
	 * 构造方法私有
	 */
	private HungryManSingleton() {
		// TODO Auto-generated constructor stub
	}
	
	/**
	 *饿汉式单例实现 
	 */
	private static final HungryManSingleton hungryMan = new HungryManSingleton();
	
	/**
	 * 获取实例
	 */
	public static HungryManSingleton getInstance() {
		return hungryMan;
	}
}

一般用于枚举法:

enum Single {
    Single;

    private Single() {
        
    }

    public void print(){
        System.out.println("hello world");
    }
}
public class SingleDemo {
    public static void main(String[] args) {
        Single a = Single.Single;
        a.print();
    }

 

懒汉式:

代码实现

 

public class LazySingleton {
	
	private LazySingleton() {
		// TODO Auto-generated constructor stub
	}
	
	private static LazySingleton lazySingleton;
	
	public synchronized static LazySingleton getInstance() {
		if (lazySingleton == null) {
			System.out.println("第一次调用的实例化。");
			lazySingleton = new LazySingleton();
		}
		return lazySingleton;
	}
}

 

区别 :饿汉式是先定义实例的 而懒汉式是先定义引用,当懒汉式第一次调用getInstance的时候 进行对象实例化操作;当然这里考虑到多并发的情况,多个线程同时调用这个方法的时候,会出现问题,所以加上同步锁 synchronized 来保证同一时刻只有一个线程进入方法。

文章出处:

https://www.cnblogs.com/nolonely/p/5927957.html

http://blog.java1234.com/blog/articles/197.html

你可能感兴趣的:(Java笔记)