设计模式: 对问题行之有效的解决方式, 其实它是一种思想.

单例设计模式

解决的问题:就是可以保证一个类在内存中的对象唯一性. 即单个实例.

比如对于A 和 B 两个程序使用同一个配置信息对象时, A 对配置信息作出修改, B 也与之对应的更新配置信息, 即需要保证该对象的唯一性.

如何保证对象唯一性呢?
  1. 不允许其他程序用 new 创建该类对象
  2. 在该类中创建一个本类实例
  3. 对外提供一个方法让其他程序可以获取该对象.
步骤:
  1. 私有化该类构造函数
  2. 通过 new 在本类中创建一个本类对象
  3. 定义一个公有方法, 将创建的对象返回
两种方式
  1. 饿汉式: 类一加载, 对象就存在了.
  2. 懒汉式: 类加载进来, 没有对象, 只有调用 getInstance 方法时, 才会创建对象.

    也称为 单例设计模式的延迟加载模式. 但是, 懒汉式在多线程访问时,存在安全隐患.
// 第一种方式: 饿汉式
class Single
{
Single s = new Single(); // 在本类中创建一个本类对象 private Single(){} // 私有化该类构造函数 // 定义一个公有方法, 将创建的对象返回. 用于返回对象 s, 所以返回类型 Single
public Single getInstance()
{
return s;
}
} class SingleDemo
{
public static void main(String[] args)
{
Single ss = Single.getInstance();
}
} /*
分析一: main 函数中, getInstance 方法调用不能使用对象调用, 只能使用类名调用.
所以 Single 类中该方法需要使用 static 修饰.
分析二: getInstance 方法为静态方法, 它访问的内容必须是静态的,所以对象 s 也需要静态修饰.
*/
// 改进
class Single
{
private static Single s = new Single(); private Single(){} public static Single getInstance() // 提供该方法访问实例对象 s, 是为了对象的可控
{
return s;
}
} class SingleDemo
{
public static void main(String[] args)
{
Single ss = Single.getInstance();
}
} // 第二种方式: 懒汉式
// 类加载进来, 没有对象, 只有调用 getInstance 方法时, 才会创建对象.
class Single2
{
private static Single2 s = null; private Single(){} public static Single2 getInstance()
{
if(s==null)
s = new Single2();
return s;
}
}
// 示例:下列代码的输出结果
class SingleDemo
{
public static void main(String[] args)
{
Test t1 = Test.getInstance();
Test t2 = Test.getInstance();
t1.setNum(10);
t2.setNum(20);
System.out.println(t1.getNum()); // 输出 20
System.out.println(t2.getNum()); // 输出 20
}
} class Test
{
private int num; private static Test t = new Test();
private Test(){}
public static Test getInstance()
{
return t;
} public void setNum(int num)
{
this.num = num;
} public int getNum()
{
return num;
}
} // 懒汉式二:避免多线程同时调用getInstance()方法, 可以使用关键字synchronized
class LazySingleton {
private static LazySingleton instance = null; private LazySingleton(){} public synchronized static LazySingleton getInstance() {
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
} // 懒汉式三:为提高系统性能,对"instance = new LazySingleton()"进行锁定
class LazySingleton{
private static LazySingleton instance = null; private LazySingleton(){} public static LazySingleton getInstance(){
if(instance == null){ // 此处,有可能造成单例对象不唯一
synchronized(LazySingleton.class){
instance = new LazySingleton();
}
}
return instance;
}
} // 懒汉式四:双重检查锁定(Double-Check Locking)
class LazySingleton{
// 注意,此处增加修饰符 volatile
private volatile static LazySingleton instance = null; private LazySingleton(){} public static LazySingleton getInstance(){
// 第一重判断
if(instance == null){
// 锁定代码块
synchronized(LazySingleton.class){
// 第二重判断
if(instance == null){
instance = new LazySingleton();
}
}
}
return instance;
}
} //单例第三种方式: Initialization Demand Holder(IoDH)技术
// 在单例类中增加一个静态(static)内部类
class Singleton{
private Singleton(){} // 静态类
private static class HolderClass {
private final static Singleton instance = new Singleton();
} public static Singleton getInstance() {
return HolderClass.instance;
} public static void main(String args[]){
Singleton s1, s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
System.out.println(s1 == s2);
}
}

_参考资料_
- [JavaSE 基础视频(毕向东)](https://www.bilibili.com/video/av3092292/#page=4)
- [单例模式中的双重检查](http://blog.csdn.net/chenchaofuck1/article/details/51702129)

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

  1. java的单例设计模式

    java的单例设计模式包括:饿汉设计模式和懒汉设计模式: 步骤: 1.创建一个对象把他设置为私有的成员变量,保证唯一 2.私有构造方法,防止new一个对象. 3.定义一个公开的静态方法,返回第一步创建 ...

  2. Java中如果把构造方法也私有化,如何创建对象?Java的单例设计模式——饿汉式和懒汉式区别

    Java的单例模式——饿汉式 package com.swift; //Java单例设计模式——恶汉式 public class SinglePerson { private String name= ...

  3. 【设计模式】Java之单例设计模式

    1.单例设计模式:一个类只能有一个对象 1.1 创建单例类的步骤: 1.将构造方法私有化 2.创建私有的静态成员变量 3.共有的静态成员方法,提供当前的唯一对象 1.1 创建单例的两种方式: 1.饿汉 ...

  4. java singleton(单例设计模式)

    单例设计模式的主要作用是: 1.控制资源的使用,我们对资源使用线程同步来实现并发访问. 2.节约资源,我们对一个类只进行一个实例化进行全局的资源访问,节约了内存. 3.作为通信媒介,也是数据共享,可以 ...

  5. 【Java】单例设计模式

    文章目录 单例设计模式 什么是设计模式 单例设计模式 实现 饿汉式 懒汉式 饿汉式与懒汉式的区别 饿汉式 懒汉式 单例模式的应用场景 单例设计模式 什么是设计模式 设计模式是在大量的实践中总结和理论化 ...

  6. java之单例设计模式

    什么是设计模式? 设计模式是在大量的实践中总结和理论化之后优选的代码结构.编程风格.以及解决问题的思考方式.设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和探索. 所谓单例 ...

  7. 【14】-java的单例设计模式详解

    预加载模式 代码: public class Singleton { private volatile static Singleton singleton = new Singleton(); pr ...

  8. java基础——单例设计模式(懒汉式)

    public class Test7 { // 主函数 public static void main(String[] args) { Test7.getInstance().function(9, ...

  9. Java学习笔记——单例设计模式Singleton

    单例设计模式:singleton 解决的问题: 确保程序在运行过程中,某个类的实例instance只有一份. 特点: 1 构造函数私有化 2 自己内部声明自己 3 提供一个public方法,负责实例化 ...

随机推荐

  1. PHP下用Memcache 实现消息队列

    Memcache 一般用于缓存服务.但是很多时候,比如一个消息广播系统,需要一个消息队列.直接从数据库取消息,负载往往不行.如果将整个消息队列用一个key缓存到memcache里面, 对于一个很大的消 ...

  2. C# DateTime 时间格式

    //2008年4月24日 System.DateTime.Now.ToString("D"); //2008-4-24 System.DateTime.Now.ToString(& ...

  3. 多线程-Thread、Runnable、Callbale、Future

    Thread:java使用Thread代表线程,所有的线程对象都必须是Thread类或其子类,可以通过继承Thread类来创建并启动多线程. package org.github.lujiango; ...

  4. 0044 spring框架的applicationContext.xml的命名空间

    Spring框架中,创建bean,装配bean,事务控制等,可以用xml配置或者注解扫描的方法实现.如果用注解扫描,在xml配置中得加上 <context:component-scan base ...

  5. oracle9i 精简版客户端界面没有显示实例名

    1.右击"我的电脑",选择"属性"菜单项 2.在弹出的窗口中,点击"高级系统设置" 3.在弹出的窗口中,选择"环境变量" ...

  6. Unity—JsonFx序列化场景

    场景数据类: /// <summary> /// 关卡数据 /// </summary> public class LevelData {     //关卡名称     pub ...

  7. Intellij IDEA常用快捷键整理

    ps:使用Intellij IDEA编辑器有蛮长一段时间了.哈哈.整合一下常用的快捷.避免自己以后还要再找. 顺序大概就是从上到下的 Alt + ENTER : 自动修正,提示Alt + Insert ...

  8. hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)

    /** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...

  9. Linux----文件I/O

    1.文件描写叙述符:每次我们打开一个文件,就会得到一个相应于该文件的较小的整数,这个整数就是这个文件的文件描写叙述符. 在shell操作中,0,1,2这三个文件描写叙述附总是打开的.一般是指向shel ...

  10. 解决 Visual Studio For Mac 还原包失败问题

    体验了一把改名部最新的杰作,总体感觉挺好,也能看出微软在跨平台这方面所做出的努力. 可能是预览版的缘故,还是遇到一个比较大的问题,创建netcore项目后,依赖包还原失败,错误信息如下: 可以先试着手 ...