单例模式

来源:互联网 发布:mac 上传文件到服务器 编辑:程序博客网 时间:2024/06/18 06:00

单例模式(Singleton Pattern)

概述

单例设计模式,简单来说就是一个类始终只能产生一个对象。使用单例模式可以有效节省内存资源,在一些环境配置的类中,一个服务器的软件启动以后,只需要加载一次就可以了。例如多个程序读取一个配置文件时,建议把配置文件封装成对象。会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的。使用单例模式保证一个类在内存中的对象唯一性。

单例模式的实现步骤

  1. 私有化构造函数
  2. 创建私有并静态的本类对象
  3. 定义公有并静态的方法,返回该对象

饿汉式和懒汉式

饿汉式:在类加载的时候就创建好一个对象,以后每次都返回创建好的这个对象。

//饿汉式class Single{    private Single(){    } //私有化构造函数。private static Single s = new Single(); //创建私有并静态的本类对象。    public static Single getInstance(){ //定义公有并静态的方法,返回该对象。        return s;    }}

懒汉式:一开始不创建对象,等需要用的时候才创建对象。在需要的时候才占用资源,懒加载对象。

//懒汉式(lazyload 延迟加载)class Single{    private Single(){    }private static Single s = null;    public static Single  getInstance(){        if(s==null)            s = new Single ();        return s;    }}

单例模式经典实现方法

方法一:package com.singleton;public class Single{    private Single(){    } //私有化构造函数。private static Single s = new Single(); //创建私有并静态的本类对象。    public static Single getInstance(){ //定义公有并静态的方法,返回该对象。        return s;    }}方法二:package com.singleton;public class Single{    public static final Single s=new Single();    private Single(){    }}方法三:(枚举实现)package com.singleton;public enum SingleEnum{    INSTANCT;}

单例模式的线程安全问题

在Web项目中,每个 HTTP Request 请求到 J2EE的容器上后都创建了一个线程,每个线程都要创建同一个单例对象。如果同时有多个线程访问程序,可能会出现多个对象实例,会造成业务逻辑混乱,数据不不一致等问题。
解决方法:
1) 使用同步方法:
public static synchronized Single getInstance()
2) 使用同步代码块:
synchronized (Single.class)

//使用同步代码块class Single {    private static Single s = null;     //1) 把构造方法设置成私有的    private Single() {    }    //2) 提供一个公共的静态的方法产生对象    public static Single getInstance() {        if (s==null) {            synchronized (Single.class) {  //判断同步锁,是需要消耗资源                if (s == null) {  //必须加上                    try {                        Thread.sleep(5);                    } catch (Exception e) {                        e.printStackTrace();                    }                    s = new Single();                }            }        }        return s;    }    }
//使用同步方法 class Single {private static final Single s= new Single();// 限制住不能直接产生一个实例private Single(){}public synchronized static Single getInstance(){return s;}}
0 0