单利模式:确保一个类最多只有一个实例,并提供一个全局访问点

  经典单利模式创建对象代码  

public class Singleton {
private static Singleton uniqueInstance = null;
private Singleton(){ }
public static Singleton getInstance(){
if (uniqueInstance==null) {
uniqueInstance=new Singleton();
}
return uniqueInstance;
}
}

  问题:多线程

public class Q {
//多线程
private static Q uniqueInstance = null;
private Q(){ }
public static Q getInstance(){
if (uniqueInstance==null) {//当线程1执行此语句后,判断通过,
/*正准备执行uniqueInstance=new Q()时,线程2抢占到了cpu资源,
*切换到线程2开始执行,线程2会发现uniqueInstance还是null,所以会创建对象,创建完后,
*而当切换到线程1时,发现线程1已经进入if判断,所以也会创建一个新uniqueInstance,
*此时线程1创建的uniqueInstance和线程2创建的uniqueInstanc是不一样的
**/
uniqueInstance=new Q();
}
return uniqueInstance;
}
}

  解决办法

  1、创建对象的方法加同步锁

/**
* 优化方式1
* 方法添加同步锁
* 优点:使用方便
* 缺点:当线程很多的情况下,非常耗费资源
* @author yxm
*
*/
public class Optimization_Singleton_1 {
private static Optimization_Singleton_1 uniqueInstance = null;
private Optimization_Singleton_1(){ }
public synchronized static Optimization_Singleton_1 getInstance(){
if (uniqueInstance==null) {
uniqueInstance=new Optimization_Singleton_1();
}
return uniqueInstance;
}
}

  2、饿汉式创建对象

/**
* 优化方式2
* 急切创建对象
* 优点:不会因为加锁而耗费资源
* 缺点:当不使用此类时,照样会耗费内存
* @author yxm
*
*/
public class Optimization_Singleton_2 {
private static Optimization_Singleton_2 uniqueInstance = new Optimization_Singleton_2();
private Optimization_Singleton_2(){ }
public static Optimization_Singleton_2 getInstance(){
if (uniqueInstance==null) {
uniqueInstance=new Optimization_Singleton_2();
}
return uniqueInstance;
}
}

  3、双重检查加锁 (较完美)

/**
* 优化方式3
* 双重检查加锁
* 较完美
* @author yxm
*
*/
public class Optimization_Singleton_3 {
private volatile static Optimization_Singleton_3 uniqueInstance = null;//volatile给编译器使用,保证线程安全
private Optimization_Singleton_3(){ }
public synchronized static Optimization_Singleton_3 getInstance(){
if (uniqueInstance==null) {
       //只有等线程1把对象创建好了,其他线程才会进入以下代码块
synchronized(Optimization_Singleton_3.class){
if (uniqueInstance==null) {
uniqueInstance=new Optimization_Singleton_3();
}
}
}
return uniqueInstance;
}
}

  案例:一个巧克力工厂,生产各式各样的巧克力,生产过程有(准备原料、填充、加热、排出)四道工序,但是现在工厂里只有一条生产线,意味着一次只能生产一种巧克力,请问如何把控?

  分析:转换为计算机思维,此场景是典型的一个类只能有一个对象,符合单利模式特征

  普通巧克力工厂

public class ChocolateFactory {
private boolean empty;
private boolean boiled; public ChocolateFactory(){
empty=true;
boiled=false;
}
//填充
public void fill(){
if (empty) {
empty=false;
boiled=false;
}
}
//加热
public void boil(){
if (!boiled) {
boiled=true;
}
}
//排出
public void drain(){
if (!empty&&boiled) {
empty=true;
}
}
}

  使用单利模式后的巧克力工厂

public class ChocolateFactoryInSingleton {
private boolean empty;
private boolean boiled;
public static ChocolateFactoryInSingleton uniqueInstance=null;
private ChocolateFactoryInSingleton(){
empty=true;
boiled=false;
}
public static ChocolateFactoryInSingleton getInstance(){
     //此处确保不同的巧克力不会进入同一条生产线
if (uniqueInstance==null) {
uniqueInstance=new ChocolateFactoryInSingleton();
}
return uniqueInstance;
}
//填充
public void fill(){
if (empty) {
empty=false;
boiled=false;
}
}
//加热
public void boil(){
if (!boiled) {
boiled=true;
}
}
//排出
public void drain(){
if (!empty&&boiled) {
empty=true;
}
}
}

Java设计模式の单利模式的更多相关文章

  1. java设计模式 --------单利模式

    解法一:只适合单线程环境(不好) package test; /** * @author xiaoping * */ public class Singleton { private static S ...

  2. Java设计模式——组合模式

    JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...

  3. java设计模式--单列模式

    java设计模式--单列模式 单列模式定义:确保一个类只有一个实例,并提供一个全局访问点. 下面是几种实现单列模式的Demo,每个Demo都有自己的优缺点: Demo1: /** * 单列模式需要满足 ...

  4. 3.java设计模式-建造者模式

    Java设计模式-建造者模式 在<JAVA与模式>一书中开头是这样描述建造(Builder)模式的: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal repr ...

  5. Java设计模式-代理模式之动态代理(附源代码分析)

    Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...

  6. Java设计模式——外观模式

    JAVA 设计模式 外观模式 用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构

  7. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...

  8. 【设计模式】Java设计模式 - 原型模式

    [设计模式]Java设计模式 - 原型模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...

  9. 【设计模式】Java设计模式 - 桥接模式

    [设计模式]Java设计模式 - 桥接模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...

随机推荐

  1. python字符串填充(转)

    ljust()方法返回字符串左对齐的字符串长度宽度.填充是通过使用指定的fillchar(默认为空格).如果宽度小于len(s)返回原始字符串.语法 以下是ljust()方法的语法: str.ljus ...

  2. mysql优化连接数

    很多开发人员都会遇见”MySQL: ERROR 1040: Too many connections”的异常情况,造成这种情况的一种原因是访问量过高,MySQL服务器抗不住,这个时候就要考虑增加从服务 ...

  3. 在Windows下远程连接CentOS6

    远程连接linux服务器的方式:以显示的类型来分类,可以分为字符界面和图形界面两种.字符界面软件有SecureCRT.PUTTY等:图形界面有Xmanager.Xdmcp和VNC软件等.

  4. java并发中的锁

    java中的锁,最基本的是Lock接口. Lock接口中的方法,主要是: lock(): 获取锁,lock()方法会对Lock实例对象进行加锁,因此所有对该对象调用lock()方法的线程都会被阻塞,直 ...

  5. Food(最大流)

    Food http://acm.hdu.edu.cn/showproblem.php?pid=4292 Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  6. 二叉树中的最大路径和 · Binary Tree Maximum Path Sum

    [抄题]: 给出一棵二叉树,寻找一条路径使其路径和最大,路径可以在任一节点中开始和结束(路径和为两个节点之间所在路径上的节点权值之和) [思维问题]: 不会写分合法 [一句话思路]: 用两次分治:ro ...

  7. php反射机制学习

    PHP 5 具有完整的反射 API,可以通过反射机制来获取类,接口,函数的详细信息.例如可以通过反射api的成员属性,成员方法,命名空间的名称,检测某个类是否为抽象类等操作.(欢迎指点) 一般用途是在 ...

  8. CodeSmith生成SQL Server视图的实体类脚本/对应的生成模板

    C#生成sql视图的实体类 using System;using System.Text;using CodeSmith.Engine;using SchemaExplorer;using Syste ...

  9. Golang之写一个聊天室

    . 海量用户在线聊天系统 . 点对点聊天 . 用户登录&注册 一.服务端开发 . 用户管理 用户id:数字 用户密码:字母数字组合 用户昵称:用来显示 用户性别:字符串 用户头像:url 用户 ...

  10. Python Socket 编程详细介绍(转)

    Python 提供了两个基本的 socket 模块: Socket 它提供了标准的BSD Socket API. SocketServer 它提供了服务器重心,可以简化网络服务器的开发. 下面讲解下 ...