单例模式

原创 2015年11月20日 14:59:22

单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。

单例模式:就是确保对象只有一个。

满足的条件:

(1)构造方法私有

(2)提供当前对象作为属性

(3)提供一个共有的方法,返回当前对象的实例


满足单例模式有以下几种写法  :

(1)饿汉式

package singleton;


public class EagerSingleton {


/**
* @yy
* 饿汉式
*/

private int count=0;
private EagerSingleton(){
this.count++;
}

private static EagerSingleton singleton=new EagerSingleton();

public static EagerSingleton getInstance(){
return singleton;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}


public static void main(String[] args) {

EagerSingleton singleton=EagerSingleton.getInstance();
System.out.println(singleton.getCount());
EagerSingleton singleton1=EagerSingleton.getInstance();
System.out.println(singleton1.getCount());
}


}

(2)懒汉式

package singleton;


/*
 * yy
 * 懒汉式
 * */
public class LazySingleton {


private static int count=0;
private LazySingleton(){
count++;
}

private static LazySingleton singleton=null;

/*对于高并发的情况下,使用synchronized关键字,会使整个系统的并发性能下降,synchronized是
* 重量级的锁,因此需要慎重的使用
*/

public  synchronized static LazySingleton getInstance(){
if(singleton==null){
singleton=new LazySingleton();
}
return singleton;
}

public static int getCount() {
return count;
}
public static void setCount(int count) {
LazySingleton.count = count;
}

public static void main(String[] args) {
LazySingleton object=LazySingleton.getInstance();
System.out.println(object.getCount());
LazySingleton object1=LazySingleton.getInstance();
System.out.println(object1.getCount());

}


}

由于多线程的并发,饿汉式不会有任何的问题,但是懒汉式会出现创建多个对象的情况。

(3)在懒汉式的基础上提出双重检查的策略

package singleton;


public class LazySingleton_DoubleCheck {


/**
* @yy

*/

/*关键字volatile的使用,在多线程情况下,volatile修饰的变量不能被修改,否则会出现不一致性
* volatile底层主要主要使用的CAS+不断的重试
* volatile修饰的变量,每一次都是从内存中获取新的值。
* 这个双重检查,主要就是可以减少synchronized锁的线程切换
*/

private int count=0;
private volatile static LazySingleton_DoubleCheck singleton=null;

private LazySingleton_DoubleCheck(){
count++;
}

public static LazySingleton_DoubleCheck getInstance(){
if(singleton==null){
synchronized(LazySingleton_DoubleCheck.class){
if(singleton==null){
singleton=new LazySingleton_DoubleCheck();
}
}
}
return singleton;
}

public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}


public static void main(String[] args) {
for(int i=0;i<30;i++){
new Thread(){
public void run(){
LazySingleton_DoubleCheck instance=LazySingleton_DoubleCheck.getInstance();
System.out.println(Thread.currentThread().getName()+"-------------count:  "+instance.getCount());
}
}.start();

new Thread(){
public void run(){
LazySingleton_DoubleCheck instance=LazySingleton_DoubleCheck.getInstance();
System.out.println(Thread.currentThread().getName()+"-------------count:  "+instance.getCount());
}
}.start();

}
}


}

饿汉式与懒汉式的区别:

饿汉式单例类在类被加载时就将自己实例化,它的优点在于无须考虑多线程访问问题,可以确保实例的唯一性;从调用速度和反应时间角度来讲,由于单例对象一开始就得以创建,因此要优于懒汉式单例。但是无论系统在运行时是否需要使用该单例对象,由于在类加载时该对象就需要创建,因此从资源利用效率角度来讲,饿汉式单例不及懒汉式单例,而且在系统加载时由于需要创建饿汉式单例对象,加载时间可能会比较长。

      懒汉式单例类在第一次使用时创建,无须一直占用系统资源,实现了延迟加载,但是必须处理好多个线程同时访问的问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费大量时间,这意味着出现多线程同时首次引用此类的机率变得较大,需要通过双重检查锁定等机制进行控制,这将导致系统性能受到一定影响。

(4)使用IoDH的方式,既可以解决饿汉式的内存的问题,也可以解决多线程并发锁开销的问题

package singleton;


public class IoDHSingleton {


/*
* 使用IoDH的方式解决饿汉式以及懒汉式的不足:
* 饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。
* */

private IoDHSingleton(){}

private static class HolderClass{
private static final IoDHSingleton singleton=new IoDHSingleton();
}

public static IoDHSingleton getInstance(){
return HolderClass.singleton;
}

public static void main(String[] args){
IoDHSingleton s1,s2;
s1=IoDHSingleton.getInstance();
s2=IoDHSingleton.getInstance();
System.out.println(s1==s2);
}
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

单例模式java代码

  • 2017年12月04日 19:46
  • 32KB
  • 下载

多种单例模式

  • 2017年11月30日 19:05
  • 3KB
  • 下载

java 单例模式的好处

http://blog.csdn.net/xiaolongyiqi/archive/2009/02/23/3928509.aspx http://crazyfeng.javaeye.com/blog...

单例模式

  • 2015年06月24日 10:08
  • 21KB
  • 下载

Android线程池+单例模式+webService

  • 2017年11月01日 10:36
  • 50.14MB
  • 下载

Dojo单例模式之防止TabContainer实例化多次

现在单例模式越来越成熟了,很多编程语言通过组件的一个属性就可以防止模块被实例化多次,然而处于朝阳期发展的Dojo来说,并没有对它的组件实现这一功能。所以,在某些情况下,我们必须要手动控制防止一个Wid...
  • shehun1
  • shehun1
  • 2012年08月10日 14:32
  • 2611

单例模式

  • 2013年11月14日 14:44
  • 24KB
  • 下载

单例模式详解

  • 2014年06月06日 00:14
  • 25KB
  • 下载

DCL双检测锁机制-实现单例模式的缺陷与改进

单例模式的实现方式: 1、静态内置类-实现单例模式(推荐) 2、DCL双检测锁机制-实现单例模式(缺陷:成员变量的初始化有多线程安全问题) 3、饿汉式初始化-实现单例模式 4、static代码块...
  • sinlff
  • sinlff
  • 2017年06月06日 10:31
  • 411

单例模式学习

  • 2013年01月06日 15:20
  • 3KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:单例模式
举报原因:
原因补充:

(最多只允许输入30个字)