6

设计模式 | 享元模式

 1 year ago
source link: https://benpaodewoniu.github.io/2022/12/29/designthinkings14/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

享元模式指的是可以重复利用之前创建的对象。

比如,Long 的 valueOf

public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}

l 的值在 -128127 之间的时候,会直接从缓存中返回,而不是创建新的。

案例 自定义连接池

package com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.*;

@Slf4j(topic = "c.Test")
public class Run {

public static void main(String[] args) throws InterruptedException {
Pool pool = new Pool(2);
for(int i = 0;i < 5;i++){
new Thread(() -> {
Connection connection = pool.borrow();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
pool.free(connection);
}).start();
}
}
}

@Slf4j(topic = "c.Pool")
class Pool {
// 连接池大小
private final int poolSize;
// 连接对象数组
private Connection[] connections;

// 连接状态数组 0 表示空闲 1 表示繁忙
private AtomicIntegerArray states;

//构造方法
public Pool(int poolSize) {
this.poolSize = poolSize;
this.connections = new Connection[poolSize];
this.states = new AtomicIntegerArray(new int[poolSize]);

for (int i = 0; i < poolSize; i++) {
connections[i] = new MockConnection();
}
}

// 连接
public Connection borrow() {
while (true) {
// 获取空闲连接
for (int i = 0; i < poolSize; i++) {
if (states.get(i) == 0) {
// 弄成线程安全的
if (states.compareAndSet(i, 0, 1)) {
log.debug("使用");
return connections[i];
}
}
}
// 如果没有空闲连接,当前线程进入等待
synchronized (this) {
try {
log.debug("等待");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

// 归还链接
public void free(Connection connection) {
for (int i = 0; i < poolSize; i++) {
if (connections[i] == connection) {
log.debug("归还");
states.set(i, 0);
synchronized (this) {
log.debug("唤醒");
this.notifyAll();
}
break;
}
}
}
}

class MockConnection implements Connection {
...
}
21:05:21.246 [Thread-1] DEBUG c.Pool - 使用
21:05:21.246 [Thread-0] DEBUG c.Pool - 使用
21:05:21.246 [Thread-2] DEBUG c.Pool - 等待
21:05:21.250 [Thread-4] DEBUG c.Pool - 等待
21:05:21.250 [Thread-3] DEBUG c.Pool - 等待
21:05:22.250 [Thread-1] DEBUG c.Pool - 归还
21:05:22.250 [Thread-0] DEBUG c.Pool - 归还
21:05:22.250 [Thread-0] DEBUG c.Pool - 唤醒
21:05:22.250 [Thread-3] DEBUG c.Pool - 使用
21:05:22.250 [Thread-2] DEBUG c.Pool - 等待
21:05:22.250 [Thread-4] DEBUG c.Pool - 使用
21:05:22.250 [Thread-1] DEBUG c.Pool - 唤醒
21:05:22.250 [Thread-2] DEBUG c.Pool - 等待
21:05:23.253 [Thread-4] DEBUG c.Pool - 归还
21:05:23.253 [Thread-3] DEBUG c.Pool - 归还
21:05:23.253 [Thread-4] DEBUG c.Pool - 唤醒
21:05:23.253 [Thread-2] DEBUG c.Pool - 使用
21:05:23.253 [Thread-3] DEBUG c.Pool - 唤醒
21:05:24.258 [Thread-2] DEBUG c.Pool - 归还
21:05:24.258 [Thread-2] DEBUG c.Pool - 唤醒

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK