单例大概是我最早产生明确模式意识的设计模式,因为它足够简单粗暴,目的足够明确。

单例么,就是不管怎么访问,都返回一个单一实例就好了,我最早应用在数据库的DBUtil中。

 public class DBUtils
{ //驱动串
private final static String Driver="com.mysql.jdbc.Driver";
//连接串
private static String url="jdbc:mysql://"+ SysProperties.MYSQL_HOST+":"+SysProperties.MYSQL_PORT+"/"+SysProperties.MYSQL_NAME+"?autoReconnect=true&autoReconnectForPools=true";
//Connection
private static Connection conn; private DBUtils()
{
} public static Connection getConnection()throws Exception
{
url="jdbc:mysql://"+SysProperties.MYSQL_HOST+":"+SysProperties.MYSQL_PORT+"/"+SysProperties.MYSQL_NAME;
CE.lgInfo("url:" + url); if(conn==null || conn.isClosed())
{
conn=DriverManager.getConnection(url, SysProperties.MYSQL_USER, SysProperties.MYSQL_PWD);
} return conn;
} }

很完美,在我的小程序里跑了近两年。

可是有的时候检查订单,就会发现每个阶段的订单都有那么几块钱无论如何对不上。这一直是个幽灵bug,困扰许久。

知道有一天,检查日志的的时候发现,当一个数据库在访问数据库进行锁表的时候,被锁内容却被另一个操作修改掉了。于是,我第一次看到了线程的影子。

但是那时候我对线程的理解完全不够透彻,只是模糊知道:

  1. 可能是有好几个请求同时访问了这个方法;
  2. 在一个请求要new Connection的时候,将new未new之际,另一个请求插队了,也挤进来了;
  3. 第二个请求一看,哦,没有connection,我也new一个,其实此时第一个请求已经在new了,只不过还没new出来而已;
  4. 结果就出来了两个Connection,单例?呵呵……

然后知道了有个关键字叫synchronized, 好,改。

     public static synchronized  Connection getConnection()throws Exception
{
url="jdbc:mysql://"+SysProperties.MYSQL_HOST+":"+SysProperties.MYSQL_PORT+"/"+SysProperties.MYSQL_NAME;
CE.lgInfo("url:" + url); if(conn==null || conn.isClosed())
{
conn=DriverManager.getConnection(url, SysProperties.MYSQL_USER, SysProperties.MYSQL_PWD);
} return conn;
}

于是变成了这样。于是,同一时间只有一个线程可以访问这个方法,其他人想访问,好,你等着吧,等我搞完你再上。

所有对该方法的请求被JVM强制排起了队,自然不会被new出来多个Connection了。

跑了半年,似乎不错。

但是后来忽然想,我之所以使用synchronized,是不想让他重复new,而不是不想让他重复访问。感觉就像什么呢,大家去生孩子,为了让医生好好工作,让大家都要排队进产房,这很正常,可是我现在除了让大家排队进产房,还让大家排队怀孕……这就扯淡了。

于是查资料,知道了synchronized不仅可以作用于方法,还可作用于区块。于是有了下面这个:

     public static synchronized  Connection getConnection()throws Exception
{
url="jdbc:mysql://"+SysProperties.MYSQL_HOST+":"+SysProperties.MYSQL_PORT+"/"+SysProperties.MYSQL_NAME;
CE.lgInfo("url:" + url); if(conn==null || conn.isClosed())
{
synchronized (DBUtil.class){
if(conn==null || conn.isClosed()){
conn=DriverManager.getConnection(url, SysProperties.MYSQL_USER, SysProperties.MYSQL_PWD);
}
}
} return conn;
}

只有为null的时候,才排队。为啥判断两次?更安全啊。

当然,后来知道了他有个更高大上的名字,称为“双重检查锁”。

所以,一个单例,真的简单么?可以用最快速的方法实现一个单例,也可以用相对更安全的方法实现一个单例。

如果你在面试,一个单例写下来,就知道你是一个菜鸟还是老手了。

DBUtil数据库连接单例 —— 简单不简单的更多相关文章

  1. Java获取Access数据库连接单例简单实例

    Java在连接Access数据库时比较方便,不用导入第三方的jar包,jdk中内置的odbc可以完成Access数据库的访问,需要注意的是,我们首先要配置Access数据库的数据源,还要区分x86和x ...

  2. php进阶学习-单例设计模式

    什么是单例模式(singleton)? 在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个,同时这个类还必须提供一个访问该类的全局访问点. 单例模式的特点 一个类只有一个实例 私有克隆 ...

  3. C#中的简单工厂和单例

    下面首先来说说简单工厂 举个例子: 首先是父类 public abstract class Pizza { public abstract string Info(); } } 子类 public c ...

  4. 从一个简单的Java单例示例谈谈并发

    一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这么写 public class UnsafeLazyInitiallization { private static Un ...

  5. 从一个简单的Java单例示例谈谈并发 JMM JUC

    原文: http://www.open-open.com/lib/view/open1462871898428.html 一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这 ...

  6. GCD实现简单的单例类-Singletion

    什么是单例模式 1.单例模式是一个类在系统中只有一个实例对象.通过全局的一个入口点对这个实例对象进行访问.在 iOS 开发中,单例模式是非常有用的一种设计模式.如 下图,是一个简单单例模式的 UML ...

  7. 简单介绍如何使用PowerMock和Mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值(转)

    本文将简单介绍如何使用PowerMock和Mockito来mock1. 构造函数2. 静态函数3. 枚举实现的单例4. 选择参数值做为函数的返回值5. 在调用mock出来的方法中,改变方法参数的值 一 ...

  8. Java单例类的简单实现

    对于java新手来说,单例类给我的印象挺深,之前一道web后台笔试题就是写单例类.*.*可惜当时不了解. 在大部分时候,我们将类的构造器定义成public访问权限,允许任何类自由创建该类的对象.但在某 ...

  9. Swift中简单的单例设计

    import Foundation class Test: NSObject { // 提供单例实例 static let shareInstance = Test() // 私有化构造方法 over ...

随机推荐

  1. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  2. 用scikit-learn学习主成分分析(PCA)

    在主成分分析(PCA)原理总结中,我们对主成分分析(以下简称PCA)的原理做了总结,下面我们就总结下如何使用scikit-learn工具来进行PCA降维. 1. scikit-learn PCA类介绍 ...

  3. SQLSERVER走起 APP隆重推出

    SQLSERVER走起 APP隆重推出 为方便大家查看本微信公众以前推送的文章,QQ群里面的某位SQLSERVER重度爱好者开发了<SQLSERVER走起>的APP 以供大家一起交流 网页 ...

  4. 领域驱动和MVVM应用于UWP开发的一些思考

    领域驱动和MVVM应用于UWP开发的一些思考 0x00 起因 有段时间没写博客了,其实最近本来是根据梳理的MSDN上的资料(UWP开发目录整理)有条不紊的进行UWP学习的.学习中有了心得体会或遇到了问 ...

  5. 首个threejs项目-前端填坑指南

    第一次使用threejs到实际项目中,开始的时候心情有点小激动,毕竟是第一次嘛,然而做着做着就感受到这玩意水好深,满满的都是坑,填都填不过来.经过老板20天惨无人道的摧残,终于小有成就. 因为第一次搞 ...

  6. Js new到底发生了什么

    在Js中,我们使用了new关键字来进行实例化 那么在这个new的过程中到底发生了什么? 关于构造函数的return 正常来讲构造函数中是不用写return语句的,因为它会默认返回新创建的对象. 但是, ...

  7. 浅谈web攻防

    CSRF 跨站请求伪造(Cross-Site Request Forgery) -原理- 从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤: 1.登录受信任网站A,并在本地生成Coo ...

  8. CRL快速开发框架系列教程九(导入/导出数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. C#向PPT文档插入图片以及导出图片

    PowerPoint演示文稿是我们日常工作中常用的办公软件之一,而图片则是PowerPoint文档的重要组成部分,那么如何向幻灯片插入图片以及导出图片呢?本文我将给大家分享如何使用一个免费版Power ...

  10. HTML5轻松实现搜索框提示文字点击消失---及placeholder颜色的设置

    在做搜索框的时候无意间发现html5的input里有个placeholder属性能轻松实现提示文字点击消失功能,之前还傻傻的在用js来实现类似功能... 示例 <form action=&quo ...