创建型模式: – 单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。

• 结构型模式: – 适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模 式。

• 行为型模式: – 模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模 式、解释器模式、状态模式、策略模式、职责链模式、访问者模式

单例模式:

• 核心作用: – 保证一个类只有一个实例,并且提供一个访问该实例的全局访问点

• 常见应用场景:

– Windows的Task Manager(任务管理器)就是很典型的单例模式 – windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

– 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,每次new一个对象去读取。

– 网站的计数器,一般也是采用单例模式实现,否则难以同步。

– 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作 ,否则内容不好追加。

– 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。

– 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。

– Application 也是单例的典型应用

– 在Spring中,每个Bean默认就是单例的,这样做的优点是Spring容器可以管理 – 在servlet编程中,每个Servlet也是单例 – 在spring MVC框架/struts1框架中,控制器对象也是单例

单例模式的优点:

– 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要 比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动 时直接产生一个单例对象,然后永久驻留内存的方式来解决 – 单例模式可以在系统设置全局的访问点,优化环共享资源访问,例如可以设计 一个单例类,负责所有数据表的映射处理

常见的五种单例模式实现方式:

– 主要: • 饿汉式(线程安全,调用效率高。 但是,不能延时加载。)

• 懒汉式(线程安全,调用效率不高。 但是,可以延时加载。)

– 其他: • 双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用)

• 静态内部类式(线程安全,调用效率高。 但是,可以延时加载)

• 枚举单例(线程安全,调用效率高,不能延时加载)

饿汉式实现(单例对象立即加载)

//饿汉式单例
public class Singleton01 {
//类初始化时,立即加载这个对象
//加载类是天然的线程安全的,(没有延时加载的优势)
private static Singleton01 instance=new Singleton01();
private Singleton01(){ }
//方法没有同步,调用效率高
public static Singleton01 getInstance(){
return instance;
}
}

  懒汉式

//懒汉式
public class Singleton02 {
//类初始化时,不初始化这个对象(真正用到的时候在创建)
private static Singleton02 instance;
private Singleton02(){ //私有构造器 }
//方法同步,调用效率低
public static synchronized Singleton02 getInstance(){
if(instance==null){
instance=new Singleton02();
}
return instance;
}
}

  双重检索:

//双重检测所机制
//由于编译器优化原因和jvm底层内部模型原因,有时候回出现问题
public class Singleton03 {
private static Singleton03 instance=null; public static Singleton03 getInstance(){
if(instance==null){
Singleton03 sc;
synchronized (Singleton03.class){
sc=instance;
if(sc==null){
synchronized(Singleton03.class){
if(sc==null){
sc=new Singleton03();
}
}
instance=sc;
}
}
}
return instance;
}
private Singleton03(){ }
}

  静态内部类:

//静态内部类
public class Singleton04 {
//要点:
//– 外部类没有static属性,则不会像饿汉式那样立即加载对象。
//– 只有真正调用getInstance(),才会加载静态内部类。加载类时是线程 安全的。
//instance是static final 类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,
//从而保证了线程安全性. – 兼备了并发高效调用和延迟加载的优势! private static class Singleton04ClassInstance {
private static final Singleton04 instance = new Singleton04();
}
private Singleton04() { }
public static Singleton04 getInstance() {
return Singleton04ClassInstance.instance;
}
}

  枚举模式:

//枚举单例(没有延时加载)
public enum Singleton05 {
//定义一个枚举,枚举 元素本身就是一个单例
INSTANCE;
//添加自己需要的元素
public void singletonOperation(){ }
}

  

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

  

常见的五种单例模式实现方式

– 主要: • 饿汉式(线程安全,调用效率高。 但是,不能延时加载。) • 懒汉式(线程安全,调用效率不高。 但是,可以延时加载。)

– 其他: • 双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题。不建议使用) • 静态内部类式(线程安全,调用效率高。 但是,可以延时加载) • 枚举式(线程安全,调用效率高,不能延时加载。并且可以天然的防止反射和反序列 化漏洞!) • 如何选用? – 单例对象  占用  资源 少,不需要  延时加载: • 枚举式   好于   饿汉式 – 单例对象  占用  资源 大,需要 延时加载: • 静态内部类式   好于  懒汉式

反射和序列化破坏单例:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor; public class SingletonTest01 {
public static void main(String[] args) throws Exception{
Singleton06 s1=Singleton06.getInstance();
Singleton06 s2=Singleton06.getInstance(); System.out.println(s1);
System.out.println(s2); //通过反射的方式直接调用私有构造器
Class<Singleton06> clazz= (Class<Singleton06>)Class.forName("demo.singleton.Singleton06");
//获取无参数构造器
Constructor<Singleton06> c=clazz.getDeclaredConstructor(null);
//跳过权限的检查
c.setAccessible(true);
Singleton06 s3=c.newInstance();
Singleton06 s4=c.newInstance(); System.out.println(s3);
System.out.println(s4); //通过序列化的方式构造多个对象
FileOutputStream fos=new FileOutputStream("d:/a.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(s1);
oos.close();
fos.close(); ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:/a.txt"));
Singleton06 s5=(Singleton06) ois.readObject();
System.out.println(s5);
}
}

  

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor; public class SingletonTest01 {
public static void main(String[] args) throws Exception{
Singleton06 s1=Singleton06.getInstance();
Singleton06 s2=Singleton06.getInstance(); System.out.println(s1);
System.out.println(s2); //通过反射的方式直接调用私有构造器
Class<Singleton06> clazz= (Class<Singleton06>)Class.forName("demo.singleton.Singleton06");
//获取无参数构造器
Constructor<Singleton06> c=clazz.getDeclaredConstructor(null);
//跳过权限的检查
c.setAccessible(true);
Singleton06 s3=c.newInstance();
Singleton06 s4=c.newInstance(); System.out.println(s3);
System.out.println(s4); //通过序列化的方式构造多个对象
FileOutputStream fos=new FileOutputStream("d:/a.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(s1);
oos.close();
fos.close(); ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:/a.txt"));
Singleton06 s5=(Singleton06) ois.readObject();
System.out.println(s5);
}
}

  测试:

import java.util.concurrent.CountDownLatch;

public class SingletonTest03 {
public static void main(String[] args) throws Exception {
long start=System.currentTimeMillis();
int threanNum=10;
final CountDownLatch countDownLath=new CountDownLatch(threanNum); for(int i=0;i<10;i++){
new Thread(new Runnable(){
@Override
public void run(){
for(int i=0;i<1000000;i++){
//Object o=Singleton04.getInstance();
Object o=Singleton05.INSTANCE;
}
countDownLath.countDown();
}
}).start();
}
countDownLath.await();//mian线程阻塞,知道计数器变成0,才会继续往下执行
long end=System.currentTimeMillis();
System.out.println("总耗时:"+(end-start));
}
}

  多线程情况的下的单例模式:

//标准的单例模式
public class SingletonDemo {
private static volatile SingletonDemo instance=null;
private SingletonDemo(){
System.out.println(Thread.currentThread().getName()+
"\t 我是构造方法SingletonDemo()");
}
//双端检索机制
public static SingletonDemo getInstance(){
if(instance==null){
synchronized (SingletonDemo.class){
if(instance==null)
instance=new SingletonDemo();
}
}
return instance;
} public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{
SingletonDemo.getInstance();
},String.valueOf(i)).start();
}
}
}

  

java设计模式单例模式的更多相关文章

  1. java设计模式单例模式 ----懒汉式与饿汉式的区别

    常用的五种单例模式实现方式 ——主要: 1.饿汉式(线程安全,调用率高,但是,不能延迟加载.) 2.懒汉式(线程安全,调用效率不高,可以延时加载.) ——其他: 1.双重检测锁式(由于JVM底层内部模 ...

  2. Java设计模式の单例模式

    -------------------------------------------------- 目录 1.定义 2.常见的集中单例实现 a.饿汉式,线程安全 但效率比较低 b.单例模式的实现:饱 ...

  3. JAVA设计模式-单例模式(Singleton)线程安全与效率

    一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...

  4. Java设计模式 - - 单例模式 装饰者模式

    Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...

  5. 【设计模式】Java设计模式 - 单例模式

    [设计模式]Java设计模式 - 单例模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 分享学习心得,欢迎指正,大家一起学习成长! 原创作品,更多关注我CSDN: ...

  6. Java 设计模式 —— 单例模式

    1. 概念: 单例模式是一种常用的软件设计模式.核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果 ...

  7. Java设计模式 - 单例模式 (懒汉方式和饿汉方式)

    概念: Java中单例模式是一种常见的设计模式,单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式的写法有好几种,这 ...

  8. java设计模式——单例模式(一)

    一. 定义与类型 定义:保证一个类仅有一个实例,并提供一个全局访问点 类型:创建型 二. 适用场景 想确保任何情况下都绝对只用一个实例 三. 优缺点 优点: 在内存里只有一个实例,减少了内存开销 可以 ...

  9. JAVA设计模式--单例模式

    单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 核心知识点如下: (1) 将采用单例 ...

  10. Java设计模式-单例模式(Singleton)

    单例对象(Singleton)是一种常用的设计模式.在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在.这样的模式有几个好处: 1.某些类创建比较频繁,对于一些大型的对象,这是一笔 ...

随机推荐

  1. 英语四6级CET6资料大学六级单词

    ambient a.周围的,包围着的 ambiguous a.模棱两可的:分歧的 ambitious a.有雄心的:热望的 ample a.足够的:宽敞的 amplitude n.广大:充足:振幅 a ...

  2. 8种常见数据结构及其Javascript实现

    摘要: 面试常问的知识点啊... 原文:常见数据结构和Javascript实现总结 作者:MudOnTire Fundebug经授权转载,版权归原作者所有. 做前端的同学不少都是自学成才或者半路出家, ...

  3. hydra使用,实例介绍

    hydra 是一个网络帐号破解工具,支持多种协议.其作者是van Hauser,David Maciejak与其共同维护.hydra在所有支持GCC的平台能很好的编译,包括Linux,所有版本的BSD ...

  4. python 登录并获取session,使用session新增ecshop的草稿

    ,"consignee":"冬天","email":"12345@qq.com","address" ...

  5. vue项目实基础到实战,入门到精通,移动商城

    最近发现许多的朋友都问我有没有vue项目的案例学习,最近正在学习vue,在这可以分享给大家,希望大家学有所成,相互交流共同进步,先不说了,吃个宵夜. 就这么多吧,需要的可以在下方留言或者加qq:116 ...

  6. tensorflow 待阅读的资料

    tensorflow性能调优实践 https://www.jianshu.com/p/937a0ce99f56 2018.04.01 Deep Learning 之 最优化方法 https://blo ...

  7. 自定义web框架(django)

    Django基础了解知识 HTTP协议(超文本传输协议) HTTP协议 四大特性: 基于TCP/IP之上作用于应用层 基于请求响应 无状态 引申出cookie session token-- 无连接 ...

  8. CF306C White, Black and White Again

    CF306C White, Black and White Again 洛谷评测传送门 题目描述 Polycarpus is sure that his life fits the descripti ...

  9. 高效Redis工具类

    一.引言 本篇博客以redis缓存为主.至于什么是redis缓存?还有没有其它的缓存?哪个缓存的性能会更好?这里就不一一做介绍了!(有兴趣的可以自己去百度一下) 在日常的开发中,我们或多或少(必须)的 ...

  10. C++面向对象程序设计学习笔记(2)

    C++在非面向对象方面的扩充 C++向下兼容C语言,因此C语言中的语法在C++中依然成立 输入输出 C++添加了标准输入流对象cin和标准输出流对象cout来进行输入输出, 例: #include&l ...