参考:
单例模式和享元模式都是为了避免重复创建对象,但是其本质是不一样的:
其实现方式不一样,单例是一个类只有一个唯一的实例,而享元可以有多个实例,只是通过一个共享容器来存储不同的对象。
其使用场景不一样,单例是强调减少实例化提升性能,因此一般用于一些需要频繁创建和销毁实例化对象或创建和销毁实例化对象非常消耗资源的类中,如连接池、线程池。而享元则是强调共享相同对象或对象属性,节约内存使用空间。
享元模式:简单来说就是池技术:通过池来限制对象的个数;
代码展示:案例:使用数据库连接池
ConnectionPool:
package com.example.dtest.design23.flyweight;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;
/*
*享元模式: 连接池模式
*Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:
Vector 是同步访问的。
Vector 包含了许多传统的方法,这些方法不属于集合框架。
Vector 主要用在事先不知道数组的大小,或者只是需要一个可以改变大小的数组的情况。
* */
public class ConnectionPool {
private Vector<Connection> pool;
/*
* 公有属性
* */
private String url = "jdbc:mysql://49.235.125.47:3306/dblogs";
private String username = "root";
private String password = "123456";
//看maven中的mysql-connector-java包的mysql中的jdbc的Driver的位置(一般重com开始)
private String driverClassName = "com.mysql.cj.jdbc.Driver";
// private String driverClassName = "com.mysql.jdbc.Driver";
private int poolSize = 10;
private static ConnectionPool instance = null;
Connection conn = null;
/*构造方法,做一下初始化工作*/
public ConnectionPool(){
pool = new Vector<Connection>(poolSize);
for(int i = 0;i < poolSize ; i++){
try {
Class.forName(driverClassName);//classLoader,加载对应驱动
conn = DriverManager.getConnection(url,username,password);
pool.add(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables){
throwables.printStackTrace();
}
}
}
/*返回连接到连接池*/
public synchronized void release(Connection conn){
pool.add(conn);
}
/*返回连接池中的一个数据库连接*/
public synchronized Connection getConnection(){
if(pool.size() > 0){
Connection conn = pool.get(0);
pool.remove(conn);
return conn;
}else {
return null;
}
}
}
测试类:
package com.example.dtest.design23.flyweight;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class flyweightTest {
public static void main(String[] args) {
//创建数据库连接池
ConnectionPool pool = new ConnectionPool();
//2、获取数据库连接
Connection conn = pool.getConnection();
//3、获取传输器
try {
Statement stat = conn.createStatement();
//4、发送SQL到服务器执行并返回执行结果
String sql = "select * from test";
ResultSet rs = stat.executeQuery(sql);
//5、处理结果
while (rs.next()){
int id = rs.getInt("id");
String name = rs.getString("test");
System.out.println(id+":"+name);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//6、释放资源
pool.release(conn);
System.out.println("TestJdbc.main()....");
}
}
}