单例模式/singleton模式/创建型模式
Java实现要点:
- 私有构造方法
- 线程安全(并发的考虑)
- 延迟加载(效率的考虑,对于较大的类在使用时在加载)
- 公有方法访问单一实例
常见单例模式代码及问题
//无延迟加载,常驻内存(即使不使用)
class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
//无延迟加载,常驻内存(即使不使用)
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 Singleton4 {
private static Singleton4 instance=null;
private Singleton4 () {
}
private static synchronized void synUnit() {
if (instance==null) {
instance=new Singleton4();
}
}
public static Singleton4 getInstance() {
if (instance==null) {
synUnit();
}
return instance;
}
}
/*
* 使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。
* 这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕,
* 这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。
*
* */
public class Singleton {
private Singleton() {}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
//单枚举类型,实现单例,无偿提供序列化,Effective Java推荐的方式。
public enum Singleton {
INSTANCE;
public void method() {
System.out.println("hello world");
}
}
总结
- synchronized关键字锁定的是对象,在用的时候,一定要在恰当的地方使用(注意需要使用锁的对象和过程,可能有的时候并不是整个对象及整个过程都需要锁)。
静态类
- 静态类不能实现接口。(从类的角度说是可以的,但是那样就破坏了静态了。因为接口中不允许有static修饰的方法,所以即使实现了也是非静态的)。
- 单例可以被延迟初始化,静态类一般在第一次加载是初始化。之所以延迟加载,是因为有些类比较庞大,所以延迟加载有助于提升性能。
- 单例类可以被继承,他的方法可以被覆写。但是静态类内部方法都是static,无法被覆写。
单例模式/singleton模式/创建型模式的更多相关文章
- 设计模式-单例模式(Singleton) (创建型模式)
//以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Singleton.h #pragma once #include<iostream> class Sin ...
- C#面向对象设计模式纵横谈——2.Singleton 单件(创建型模式)
一:模式分类 从目的来看: 创建型(Creational)模式:负责对象创建. 结构型(Structural)模式:处理类与对象间的组合. 行为型(Behavioral)模式:类与对象交互中的职责分配 ...
- FactoryMethod工厂方法模式(创建型模式)
1.工厂方法模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只 ...
- Prototype原型模式(创建型模式)
1.原型模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只有一 ...
- 工厂方法模式——创建型模式02
1. 简单工厂模式 在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...
- 设计模式(五):PROTOTYPE原型模式 -- 创建型模式
1.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.适用场景 原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对 ...
- 设计模式(二): BUILDER生成器模式 -- 创建型模式
1.定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 2.适用场景 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式 ...
- 建造者模式与原型模式/builder模式与prototype模式/创建型模式
建造者模式 定义 用于简化复杂对象的创建 JDK中的建造者模式 java.lang.StringBuilder中的append()方法,每次调用后返回修改后的对象本身. public StringBu ...
- C#设计模式--工厂模式(创建型模式)
一.简单工厂模式(UML类图): 核心类代码: public class Calc { public double NumberA { get; set; } public double Number ...
- 工厂模式/factory模式/创建型模式
工厂模式 普通工厂模式 原本需要new出来的对象,通过一个类的方法去搞定,Factory.build(parameter),类似这种. public interface Sender { public ...
随机推荐
- 在eclipse上开发hadoop2.5.2程序的快捷方法
本文仍然使用MapReduce的经典例子 WordCount来测试eclipse的开发环境. 与大部分教程不同的是,本文使用的hadoop是2.5.2的版本,相较于之前的0.X版本,hadoop 2. ...
- linux内置的审计跟踪工具------last和lastb
last是linux的一个内置工具,可以用来查看最后登录服务器的用户.它对于追踪非常有用. last命令显示的是来自/var/log/wtmp文件创建起,所有登录的用户.这个文件是一个二进制文件,不能 ...
- WPF ListView 排序
代码如下: list为ListView组件.Score为要排序的列,也是绑定的属性. CollectionViewSource.GetDefaultView(list.ItemsSource).Sor ...
- Effective C++ -----条款18:让接口容易被正确使用,不易被误用
好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...
- 【python】解压文件
参考:http://essen.iteye.com/blog/1941489 tarfile模块 具体使用方法: https://docs.python.org/2/library/tarfile.h ...
- mysql无法启动
当在安装mysql服务时,有时会遇到恶心的PID错误而导致安装后无法启动以下为针对mysql-5.5版本在安装mysql时所遇到的问题的解决方法. 1.可能是/usr/local/mysql/data ...
- 如何获取Iframe的页面控件的值
有时候我们在页面需要使用iframe的方法来引用另一个页面,虽然个人建议不要使用iframe哈,但是有些时候是没得法了才使用的咯,那么在使用的过程中也会遇到某一些问题,我将自己遇到的问题记录下来方便以 ...
- 通过颜色代码初始化UIColor
#define UIColorFromHEX(rgbValue) [UIColor \ colorWithRed:((float)((rgbValue & 0xFF0000) >> ...
- Linq查询
//Linq查询 List<A1> a1 = new List<A1>(); a1.Add(, Name = , Gender = true }); a1.Add(, Name ...
- JS获取阴历阳历和星期
获取当前阳历日期时间,阴历日期和星期,三者分开,可自行调整顺序. 新建JS文件getdates.js,代码如下:/*获取当前阳历日期*/function getCurrentDateTime() { ...