单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。
单例模式分为:饿汉和懒汉两种模式,具体应用场景,区别特点,见代码注释:
上代码如下:
public class Singleton {
/**
* @param args the command line arguments
*
*
*单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。
* 在应用这个模式时,单例对象的类必须保证只有一个实例存在。
* 许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。
* 比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,
* 然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。
* 实现单利模式的原则和过程:
* 1.单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例
* 2.单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstance时才会实例化对象)(java中饿单例模式性能优于懒单例模式,c++中一般使用懒单例模式)
* 3.单例模式要素: a.私有构造方法 b.私有静态引用指向自己实例 c.以自己实例为返回值的公有静态方法
*
*
*应用场景举例:
* 1.windows的任务管理器
* 2.windows的回收站
* 3.应用的配置文件
* 4.日志文件,便于追加
* 5.网站计数器,便于同步
* 6.数据库连接池的设计,节约打开关闭数据库的资源效率损耗
* 7.多线程的线程池,方便对线程进行控制
*
*
*/
private Singleton(){ //饿汉式
//优点:线程安全,在类加载时,创建静态对象,调用时反应迅速
} //缺点:当不用实例化时,其占用资源,使资源效率不高
private static Singleton singleton=new Singleton();
public Singleton getInstance(){
return singleton;
}
// private Singleton() { //懒汉式
// //优点:避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。
//
// }
// private static Singleton singleton = null;
//
// //缺点:
// //懒汉式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。
// public static Singleton getInstance() {
// if (singleton == null) {
// singleton = new Singleton();
// }
// return singleton;
// }
public static void main(String[] args) {
// TODO code application logic here
}
}
上面的是初级,就到这了,但是单例还有更多的变形,常用的是下面进阶的饿汉、懒汉模式;
饿汉式 (线程安全)
public class Singleton {
private final static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instence;
}
}
饿汉式(静态代码块【线程安全】)
public class Singleton {
private static Singleton instance;
static {
instance = new Singleton();
}
private Singleton() {}
public Singleton getInstance() {
return instance;
}
}
懒汉式(线程不安全)
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if(singleton== null){
singleton = new Singleton();
}
return singleton;
}
}
懒汉式(线程安全【方法同步】)
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
懒汉式(线程安全【同步代码块】)
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
singleton = new Singleton();
}
}
return singleton;
}
}
懒汉模式(线程安全【双重检查】)
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
静态内部类
public class Singleton {
private Singleton() {}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
枚举
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
一般采用饿汉式,若对资源十分在意可以采用静态内部类,不建议采用懒汉式及双重检测。