mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-04-30 06:37:36 +00:00
[Add] LockerMap, Locker 增加Locker锁对象和LockerMap锁对象存储;
[Change] CacheStoreCentral 将synchronized所使用的的锁对象由String(常量池)转换成Locker<K>以尝试减少内存占用;
This commit is contained in:
parent
44a7f49510
commit
2f647ee9fa
@ -12,6 +12,8 @@ import net.lamgc.cgj.exception.HttpRequestException;
|
||||
import net.lamgc.cgj.pixiv.PixivDownload;
|
||||
import net.lamgc.cgj.pixiv.PixivSearchLinkBuilder;
|
||||
import net.lamgc.cgj.pixiv.PixivURL;
|
||||
import net.lamgc.cgj.util.Locker;
|
||||
import net.lamgc.cgj.util.LockerMap;
|
||||
import net.lamgc.cgj.util.URLs;
|
||||
import net.lamgc.utils.encrypt.MessageDigestUtils;
|
||||
import net.lz1998.cq.utils.CQCode;
|
||||
@ -51,6 +53,8 @@ public final class CacheStoreCentral {
|
||||
central = new CacheStoreCentral();
|
||||
}
|
||||
|
||||
private final LockerMap<String> lockerMap = new LockerMap<>();
|
||||
|
||||
private CacheStoreCentral() {}
|
||||
|
||||
private final Hashtable<String, File> imageCache = new Hashtable<>();
|
||||
@ -228,15 +232,21 @@ public final class CacheStoreCentral {
|
||||
*/
|
||||
public JsonObject getIllustInfo(int illustId, boolean flushCache)
|
||||
throws IOException, NoSuchElementException {
|
||||
String illustIdStr = buildSyncKey(Integer.toString(illustId));
|
||||
Locker<String> locker = buildSyncKey(Integer.toString(illustId));
|
||||
String illustIdStr = locker.getKey();
|
||||
JsonObject illustInfoObj = null;
|
||||
if (!illustInfoCache.exists(illustIdStr) || flushCache) {
|
||||
synchronized (illustIdStr) {
|
||||
try {
|
||||
locker.lock();
|
||||
synchronized (locker) {
|
||||
if (!illustInfoCache.exists(illustIdStr) || flushCache) {
|
||||
illustInfoObj = BotGlobal.getGlobal().getPixivDownload().getIllustInfoByIllustId(illustId);
|
||||
illustInfoCache.update(illustIdStr, illustInfoObj, null);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
locker.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if(Objects.isNull(illustInfoObj)) {
|
||||
@ -255,10 +265,13 @@ public final class CacheStoreCentral {
|
||||
* @throws IOException 当Http请求处理发生异常时抛出
|
||||
*/
|
||||
public JsonObject getIllustPreLoadData(int illustId, boolean flushCache) throws IOException {
|
||||
String illustIdStr = buildSyncKey(Integer.toString(illustId));
|
||||
Locker<String> locker = buildSyncKey(Integer.toString(illustId));
|
||||
String illustIdStr = locker.getKey();
|
||||
JsonObject result = null;
|
||||
if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) {
|
||||
synchronized (illustIdStr) {
|
||||
try {
|
||||
locker.lock();
|
||||
synchronized (locker) {
|
||||
if (!illustPreLoadDataCache.exists(illustIdStr) || flushCache) {
|
||||
log.trace("IllustId {} 缓存失效, 正在更新...", illustId);
|
||||
JsonObject preLoadDataObj = BotGlobal.getGlobal().getPixivDownload()
|
||||
@ -281,6 +294,9 @@ public final class CacheStoreCentral {
|
||||
log.trace("作品Id {} preLoadData缓存已更新(有效时间: {})", illustId, expire);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
locker.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if(Objects.isNull(result)) {
|
||||
@ -292,10 +308,14 @@ public final class CacheStoreCentral {
|
||||
|
||||
public List<String> getIllustPages(int illustId, PixivDownload.PageQuality quality, boolean flushCache)
|
||||
throws IOException {
|
||||
String pagesSign = buildSyncKey(Integer.toString(illustId), ".", quality.name());
|
||||
Locker<String> locker
|
||||
= buildSyncKey(Integer.toString(illustId), ".", quality.name());
|
||||
String pagesSign = locker.getKey();
|
||||
List<String> result = null;
|
||||
if (!pagesCache.exists(pagesSign) || flushCache) {
|
||||
synchronized (pagesSign) {
|
||||
try {
|
||||
locker.lock();
|
||||
synchronized (locker) {
|
||||
if (!pagesCache.exists(pagesSign) || flushCache) {
|
||||
List<String> linkList = PixivDownload
|
||||
.getIllustAllPageDownload(BotGlobal.getGlobal().getPixivDownload().getHttpClient(),
|
||||
@ -304,6 +324,9 @@ public final class CacheStoreCentral {
|
||||
pagesCache.update(pagesSign, linkList, null);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
locker.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if(Objects.isNull(result)) {
|
||||
@ -342,10 +365,14 @@ public final class CacheStoreCentral {
|
||||
}
|
||||
|
||||
String date = new SimpleDateFormat("yyyyMMdd").format(queryDate);
|
||||
String requestSign = buildSyncKey(contentType.name(), ".", mode.name(), ".", date);
|
||||
Locker<String> locker
|
||||
= buildSyncKey(contentType.name(), ".", mode.name(), ".", date);
|
||||
String requestSign = locker.getKey();
|
||||
List<JsonObject> result = null;
|
||||
if(!rankingCache.exists(requestSign) || flushCache) {
|
||||
synchronized(requestSign) {
|
||||
try {
|
||||
locker.lock();
|
||||
synchronized (locker) {
|
||||
if (!rankingCache.exists(requestSign) || flushCache) {
|
||||
log.trace("Ranking缓存失效, 正在更新...(RequestSign: {})", requestSign);
|
||||
List<JsonObject> rankingResult = BotGlobal.getGlobal().getPixivDownload()
|
||||
@ -360,6 +387,9 @@ public final class CacheStoreCentral {
|
||||
log.trace("Ranking缓存更新完成.(RequestSign: {})", requestSign);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
locker.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.isNull(result)) {
|
||||
@ -428,11 +458,15 @@ public final class CacheStoreCentral {
|
||||
|
||||
log.debug("正在搜索作品, 条件: {}", searchBuilder.getSearchCondition());
|
||||
|
||||
String requestUrl = searchBuilder.buildURL().intern();
|
||||
Locker<String> locker
|
||||
= buildSyncKey(searchBuilder.buildURL());
|
||||
String requestUrl = locker.getKey();
|
||||
log.debug("RequestUrl: {}", requestUrl);
|
||||
JsonObject resultBody = null;
|
||||
if(!searchBodyCache.exists(requestUrl)) {
|
||||
synchronized (requestUrl) {
|
||||
try {
|
||||
locker.lock();
|
||||
synchronized (locker) {
|
||||
if (!searchBodyCache.exists(requestUrl)) {
|
||||
log.trace("searchBody缓存失效, 正在更新...");
|
||||
JsonObject jsonObject;
|
||||
@ -465,6 +499,9 @@ public final class CacheStoreCentral {
|
||||
log.trace("搜索缓存命中.");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
locker.unlock();
|
||||
}
|
||||
} else {
|
||||
log.trace("搜索缓存命中.");
|
||||
}
|
||||
@ -494,12 +531,12 @@ public final class CacheStoreCentral {
|
||||
* @param keys String对象
|
||||
* @return 合并后, 如果常量池存在合并后的结果, 则返回常量池中的对象, 否则存入常量池后返回.
|
||||
*/
|
||||
private static String buildSyncKey(String... keys) {
|
||||
private Locker<String> buildSyncKey(String... keys) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String string : keys) {
|
||||
sb.append(string);
|
||||
}
|
||||
return sb.toString().intern();
|
||||
return lockerMap.createLocker(sb.toString(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
64
src/main/java/net/lamgc/cgj/util/Locker.java
Normal file
64
src/main/java/net/lamgc/cgj/util/Locker.java
Normal file
@ -0,0 +1,64 @@
|
||||
package net.lamgc.cgj.util;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public final class Locker<K> {
|
||||
|
||||
private final LockerMap<K> fromMap;
|
||||
|
||||
private final K key;
|
||||
|
||||
private final boolean autoDestroy;
|
||||
|
||||
private final AtomicInteger lockCount = new AtomicInteger(0);
|
||||
|
||||
/**
|
||||
* 构造一个锁对象
|
||||
* @param map 所属LockerMap
|
||||
* @param key 所属Key
|
||||
*/
|
||||
Locker(LockerMap<K> map, K key, boolean autoDestroy) {
|
||||
this.fromMap = map;
|
||||
this.key = key;
|
||||
this.autoDestroy = autoDestroy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上锁
|
||||
*/
|
||||
public void lock() {
|
||||
lockCount.incrementAndGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁
|
||||
*/
|
||||
public void unlock() {
|
||||
int newValue = lockCount.decrementAndGet();
|
||||
if(newValue <= 0 && autoDestroy) {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取锁对象所属Key
|
||||
*/
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁锁对象
|
||||
*/
|
||||
public void destroy() {
|
||||
fromMap.destroyLocker(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Locker{" +
|
||||
"fromMap=" + fromMap +
|
||||
", key=" + key +
|
||||
'}';
|
||||
}
|
||||
}
|
31
src/main/java/net/lamgc/cgj/util/LockerMap.java
Normal file
31
src/main/java/net/lamgc/cgj/util/LockerMap.java
Normal file
@ -0,0 +1,31 @@
|
||||
package net.lamgc.cgj.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class LockerMap<K> {
|
||||
|
||||
private final HashMap<K, Locker<K>> lockerHashMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 创建锁
|
||||
* @param key Key
|
||||
* @return 如果Key所属锁存在, 则返回对应锁, 否则返回新锁
|
||||
*/
|
||||
public Locker<K> createLocker(K key, boolean autoDestroy) {
|
||||
if(lockerHashMap.containsKey(key)) {
|
||||
return lockerHashMap.get(key);
|
||||
}
|
||||
Locker<K> newLocker = new Locker<>(this, key, autoDestroy);
|
||||
lockerHashMap.put(key, newLocker);
|
||||
return newLocker;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁锁
|
||||
* @param locker 锁对象
|
||||
*/
|
||||
public void destroyLocker(Locker<K> locker) {
|
||||
lockerHashMap.remove(locker.getKey());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user