转 本文永久链接地址:http://ilvc.me/blog/post/57
设计模式之单例模式
模式关键要素:
模式名称(Pattern name)
问题(Problem)
解决方案(Solution)
效果(Consequence)
模式名称
单例模式(Singleton Pattern)
定义:确保一个类之后一个实例化并向整个系统提供这个实例,这个类称为单例类,提供了全局访问的方法。单例模式是一种对象创建型模式。
单例模式3个要点:
- 某个类只能有一个实例
- 它必须自行创建这个实例
- 它必须自行向整个系统提供这个实例
问题:(动机)
对一个软件系统中的某些类来说不需要创建多个实例。例如windos任务管理器
解决方案
单例模式有三种实现方式:
- 饿汉式单例(Eager Singlenton)
- 懒汉式单例(Lazy Singlenton)
- Initialization on Demend Holder(IoDH)技术(注:有的面向对象语言不支持)
最简单的实现
饿汉式单例(Eager Singleton)
懒汉式单例(Layz Singleton)
Initialization on Demand Holder(IoDH) 技术
单例模式 实战:数据库连接池
/**
* Created by iLvc on 2017/6/29.
* 单例模式 实战 - 数据库连接池
*
* 只要返回一个 connection 对象,
*/
public class ConnectionPool {
// 声明 connectionList 来保存来connection对象 ,应该应map 来做
private static List<Connection> connectionList = new ArrayList<Connection>();
private static int size = 10 ; // 连接池大小
private static String user="root";
private static String url="jdbc:mysql://localhost:3306/db_lvcblog";
private static String pws="lvc159357";
private int useSize[] = new int[size];
//
private ConnectionPool() {
initConnectionPool();
}
private static class HolderClass{
private static final ConnectionPool conectionPool = new ConnectionPool();
}
public static ConnectionPool getInstance() {
return HolderClass.conectionPool;
}
// 初始化 连接池
private static void initConnectionPool(){
for (int i=0;i<size;i++){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con= (Connection) DriverManager.getConnection(url, user, pws);
connectionList.add(con);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 获取 connection
// 要保证 这个Connection 不能被使用了
public Connection getConnection(){
int number =0 ;
// 这里有问题
/* if (useSize[0] == 0 ) {
// int randomNumber = (int) Math.round(Math.random()*(max-min)+min); 获取指定范围的随机数
number = (int) Math.round(Math.random()*(size-0)+0);
useSize[0]=number;
}else{
//
}*/
number = (int) Math.round(Math.random()*(10-1)+0);
System.out.println("获取的Connection:"+number);
return connectionList.get(number);
}
// 关闭connection,释放资源
public void close(Connection connection){
try {
if (connection != null) {
connection.close();
System.out.println("关闭Connection 对象。");
}
} catch (SQLException e) {
e.printStackTrace();
}
connectionList.remove(connection);
}
// 当前有多少个连接对象
private int size(){
return connectionList.size();
}
public static void main(String[] args) {
System.out.println("连接池可用数:"+ConnectionPool.getInstance().size());
Connection con1,con2,con3;
con1 = ConnectionPool.getInstance().getConnection();
con2 = ConnectionPool.getInstance().getConnection();
// con3 = ConnectionPool.getInstance().getConnection();
if(con1.hashCode()==con2.hashCode()){
System.out.println("获取了相同的对象");
}else{
System.out.println("获取了不同的对象");
}
Daotest dao = new Daotest();
dao.selectUser(con1);
dao.selectUser(con2);
System.out.println("连接池可用数:"+ConnectionPool.getInstance().size());
}
}
测试结果:
单例模式总结: