GOF23设计模式之——单例设计模式

1.饿汉式(特点:调用效率高,不能延时加载)

//饿汉式
public public class SingletonDemo1 {
	private static SingletonDemo1 instance = new SingletonDemo1();
	private SingletonDemo1(){}
	public static SingletonDemo1 getInstance(){
		return instance;
	}
}

2.懒汉式(特点:可延时加载,调用效率低)

//懒汉式
public class SingletonDemo2{
	private static SingletonDemo2 instance;
	private SingletonDemo2(){}
	public static synchronized SingletonDemo2 getInstance(){
		if(instance==null){
			instance = new SingletonDemo2();
		}
		return instance;
	}
}

3.双重检测式(由于JVM底层原因,不可靠,避免使用)

//双重检测锁
public class SingletonDemo3{
	private static SingletonDemo3 instance;
	private SingletonDemo3(){}
	public static SingletonDemo3 getInstance(){
		if(instance==null){
			synchronized(SingletonDemo3.class){
				if(instance==null){
					instance = new SingletonDemo3();
				}
			}
		}
		return instance;
	}
}

4.静态内部类式(特点:调用效率高且可以延时加载)

//静态内部类实现方式
public class SingletonDemo4{
	private static class SingletonClassInstance{
		private static final SingletonDemo4 instance = new SingletonDemo4();
	}
	private SingletonDemo4(){}
	public static SingletonDemo4 getInstance(){
		return SingletonClassInstance.instance;
	}
}

5.枚举式(特点:调用效率高,不能延时加载,天然防止反射和反序列化漏洞)

//枚举式
public enum SingletonDemo5{
	INSTANCE;
	public void SingletonOperation(){

	}
}

对于1--4,可利用反射和反序列化破解单列,以饿汉式为例

package cn.baokx.gof23;

import java.lang.reflect.Constructor;

public class Test {
	public static void main(String[] args) throws Exception  {
		//利用反射破解单例
		Class<SingletonDemo1> clazz = (Class<SingletonDemo1>)Class.forName("cn.baokx.gof23.SingletonDemo1");
		Constructor<SingletonDemo1> c = clazz.getDeclaredConstructor(null);
		c.setAccessible(true);
		SingletonDemo1 s1 = c.newInstance();
		SingletonDemo1 s2 = c.newInstance();
		System.out.println(s1==s2);
	}
}

解决方案:

//饿汉式
public class SingletonDemo1 {
	private static SingletonDemo1 instance = new SingletonDemo1();
	private SingletonDemo1(){
		if(null==instance){
			throw new RuntimeException();
		}
	}
	public static SingletonDemo1 getInstance(){
		return instance;
	}
}
package cn.baokx.gof23;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Test {
	public static void main(String[] args) throws Exception  {
		//利用序列化破解单例
		SingletonDemo1 s1 = SingletonDemo1.getInstance();
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/obj.data"));
		oos.writeObject(s1);
		oos.close();

		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/obj.data"));
		SingletonDemo1 s2 = (SingletonDemo1)ois.readObject();
		ois.close();

		System.out.println(s1==s2);
	}
}

解决方案:

//饿汉式
public class SingletonDemo1 implements Serializable{
	private static SingletonDemo1 instance = new SingletonDemo1();
	//防反射破解单例
	private SingletonDemo1(){
		if(null==instance){
			throw new RuntimeException();
		}
	}
	public static SingletonDemo1 getInstance(){
		return instance;
	}
	//防反序列化破解单例
	private Object readResolve() throws ObjectStreamException {
		return instance;
	}
}
时间: 2024-10-17 12:26:29

GOF23设计模式之——单例设计模式的相关文章

设计模式总纲——单例设计模式

前两天写了设计模式总纲,今天就来讲讲我们在工程代码中最最最常用的设计模式了——单例设计模式,这个模式在工程代码上的出现率几乎为99.99999%,但是虽然很常用,但是用的好的人却不多,今天我们就来深入的说一说单例设计模式. 在学习一项新的知识之前,我们都要向自己提出三个问题,为什么要用这个知识,这个知识用在哪里,这个知识怎么用?既 why,where,how,3W模式,我们先来谈谈为什么需要单例设计模式,先来想想,如果一个工具类,比如一个读取配置文件的工具类,这类工具只是特定的功能类,既读取指定

java设计模式之单例设计模式

设计模式:解决某一类问题最行之有效的方法. java中23种设计模式. 单例设计模式:解决一类在内存中只存在一个对象. Runtime()方法就是单例设计模式进行设计的. 解决的问题:保证一个类在内存中的对象唯一性. 比如:多程序读取一个配置文件时,建议配置文件封装成对象.会方便操作其中数据,又要保证多个程序读到的是同一个配置文件对象,就需要该配置文件对象在内存中是唯一的. 1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象. 2.还为了让其他程序可以访问该类对象,只好在本类中自定

设计模式之-----------单例设计模式

饿汉式: class Single { //   提前做好! private static final Single s = new Single(); //  私有化 构造函数  无法使用new 创建对象! private Single(){} //  对外提供接口 public static Single getInstance() { return s; } } 懒汉式: 懒汉 顾名思义  就是懒呗 什么时候用到 什么时候创建! class Single1 { private static

java软件设计模式只单例设计模式

概述 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 设计模式分为三种类型,共23种.创建型模式:单例模式.抽象工厂模式.建造者模式.工厂模式.原型模式.结构型模式:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.

设计模式之单例设计模式

一.何为单例设计模式 单例模式,顾名思义就是单个实例,程序中某个类只有一个实例存在.通常实在需要共享某个资源避免资源损耗的情况下使用到的. 二.单例设计模式的代码实现 一说到单例模式的概念,我们首先会想到下面的这种的写法 public class SingleInstance { private static SingleInstance singleInstance; /** * 单例模式 * @return */ public static SingleInstance getSingleI

Java设计模式之单例设计模式(Singleton)

单例设计模式 单例模式在日常开发中用的也比较多,顾名思义就是一个类的对象在整个系统中只能有一个 优点: 1.单例模式会阻止其他对象实例化其自己的单例对象副本,从而确保所有对象都访问唯一实例 2.由于在整个系统中指存在一个实例对象,避免了频繁的创建和销毁对象,因此可以节约系统资源 3.避免了对共享资源的多重占用 4.自行创建这个单例对象,避免使用时再去创建 缺点: 1.单例模式没有抽象层,所以扩展性比较差 2.不适用于变化的对象,如果同一类型的对象需要在不同的场景下使用,单例就会引起数据的错误 3

java设计模式_single(单例设计模式)

设计模式:解决某一类问题最行之有效的方法,java中有23种设计模式 一.单例设计模式概述: 1.解决一个类在内存中只有一个对象(保证一个类仅有一个实例,并提供一个访问他的全局访问点)  2.要保证对象的唯一: 1.为了避免其他程序过多的建立该类对象,先禁制其他程序建立该类对象 2.为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象 3.为了 方便其他程序对自定义对象的访问,可以对外提供一些访问方式 3.代码实现步骤: 1.将构造函数私有化 2.在类中创建一个本类对象 3.给外部提供

【设计模式】单例设计模式的N中Java实现方法

特点 单例模式的特点: 1.只能有一个实例: 2.必须自己创建自己的一个实例: 3.必须给所有其他对象提供这一实例. 饿汉式单例模式 也称为预先加载法,实现方式如下: [java] view plaincopy class Single { private Single()( Syustem.out.println("ok"); ) private static Single instance = new Single(); public static Single getInstan

菜鸟之路-浅谈设计模式之单例设计模式

单例设计模式 定义:确保一个类仅仅有一个实例.并且自行实例化并向整个系统提供这个实例. 单例模式是一种经常使用的软件设计模式.在它的核心结构中仅仅包括一个被称为单例的特殊类. 通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问,从而方便对实例个数的控制并节约系统资源.假设希望在系统中某个类的对象仅仅能存在一个,单例模式是最好的解决方式. 关于单例设计模式的动机 对于系统中的某些类来说,仅仅有一个实例非常重要,比如.一个系统中能够存在多个打印任务.可是仅仅能有一个正在工作的任务:

java设计模式之单例设计模式和多例设计模式

单例设计模式:构造方法私有化,在类的内部定义static属性和方法,利用static方法来取得本类的实例化对象:无论外部产生多少个实例化对象,本质上只有一个实例化对象 饿汉式单例设计 class Singleton{ private static final Singleton INSTANCE = new Singleton();//产生一个实例化对象 private Singleton(){}//封装构造方法 public static Singleton getInstance(){ re