享元模式
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
何时使用: 1、系统中有大量对象。 2、这些对象消耗大量内存。 3、这些对象的状态大部分可以外部化。 4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。 5、系统不依赖于这些对象身份,这些对象是不可分辨的。
应用实例: 1、JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。(可参照前博文) 2、数据库的数据池。
自定义连接池
synchronized版
/**
*@ClassName CustomDataBasePool
*@Description 自定义数据库连接池 享元模式 synchronized版
**/
public class CustomConnectionPoolTest {
public static void main(String[] args) {
//测试代码
CustomConnectionPool pool = new CustomConnectionPool(2);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
Connection conn = null;
try {
conn = pool.getConn();
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
pool.backConn(conn);
},"线程"+i).start();
}
}
}
@Slf4j
class CustomConnectionPool {
private final int poolSize;
private Connection[] connections;
//用于记录每个连接是否被占用 0 表示未被占用, 1表示已被占用
private final AtomicIntegerArray stateArr;
private final Semaphore semaphore;
public CustomConnectionPool(int poolSize) {
this.poolSize = poolSize;
semaphore = new Semaphore(poolSize);
stateArr = new AtomicIntegerArray(new int[poolSize]);
connections = new Connection[poolSize];
for (int i = 0; i < connections.length; i++) {
connections[i] = new CustomConnection("连接" + i );
}
}
public Connection getConn() throws InterruptedException {
while (true) {
for (int i = 0; i < poolSize; i++) {
if (stateArr.get(i) == 0 && stateArr.compareAndSet(i, 0, 1)) {
log.info("拿到连接");
return connections[i];
}
}
synchronized (this) { //如果未获取到连接,则进入阻塞状态等待被唤醒重新获取连接
try {
log.info("进入wait");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void backConn(Connection conn) {
for (int i = 0; i < connections.length; i++) {
if (connections[i] == conn) {
log.info("归还连接");
stateArr.set(i, 0);
synchronized (this) { //归还后唤醒所有阻塞等待获取连接的线程
this.notifyAll();
}
}
}
}
}
@Slf4j
class CustomConnection implements Connection {
private String name;
public CustomConnection(String name) {
log.info("自定义{}创建成功",name);
this.name = name;
}
public String getName() {
return name;
}
/** 此处打断重写代码忽略*/
}
测试结果:
Semaphore版
/**
*@ClassName CustomDataBasePool
*@Description 自定义数据库连接池 享元模式
**/
public class CustomConnectionPoolTest {
public static void main(String[] args) {
//测试代码
CustomConnectionPool pool = new CustomConnectionPool(2);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
Connection conn = null;
try {
conn = pool.getConn();
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
pool.backConn(conn);
},"线程"+i).start();
}
}
}
@Slf4j
class CustomConnectionPool {
private final int poolSize;
private Connection[] connections;
//用于记录每个连接是否被占用 0 表示未被占用, 1表示已被占用
private final AtomicIntegerArray stateArr;
private final Semaphore semaphore;
public CustomConnectionPool(int poolSize) {
this.poolSize = poolSize;
semaphore = new Semaphore(poolSize);
stateArr = new AtomicIntegerArray(new int[poolSize]);
connections = new Connection[poolSize];
for (int i = 0; i < connections.length; i++) {
connections[i] = new CustomConnection("连接" + i );
}
}
public Connection getConn() throws InterruptedException {
semaphore.acquire();
for (int i = 0; i < poolSize; i++) {
if (stateArr.get(i) == 0 && stateArr.compareAndSet(i, 0, 1)) {
log.info("拿到连接");
return connections[i];
}
}
return null;
}
public void backConn(Connection conn) {
for (int i = 0; i < connections.length; i++) {
if (connections[i] == conn) {
log.info("归还连接");
stateArr.set(i, 0);
semaphore.release();
}
}
}
}
@Slf4j
class CustomConnection implements Connection {
private String name;
public CustomConnection(String name) {
log.info("自定义{}创建完成",name);
this.name = name;
}
public String getName() {
return name;
}
/** 此处打断重写代码忽略*/
}
测试结果: