|
|
|
@ -0,0 +1,74 @@
|
|
|
|
|
package com.mashibing.cache;
|
|
|
|
|
|
|
|
|
|
import com.mashibing.entity.Air;
|
|
|
|
|
import org.springframework.beans.factory.InitializingBean;
|
|
|
|
|
import org.springframework.stereotype.Repository;
|
|
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.concurrent.*;
|
|
|
|
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @author zjw
|
|
|
|
|
* @description
|
|
|
|
|
*/
|
|
|
|
|
@Repository
|
|
|
|
|
public class AirCache implements InitializingBean {
|
|
|
|
|
|
|
|
|
|
// 一个只有一个工作线程,并且可以执行的定时任务的线程池。
|
|
|
|
|
private static final ScheduledExecutorService AIR_POOL = Executors.newSingleThreadScheduledExecutor();
|
|
|
|
|
|
|
|
|
|
// JVM缓存 写读
|
|
|
|
|
private static final ConcurrentHashMap<Long,Air> AIR_CACHE = new ConcurrentHashMap<Long, Air>(128);
|
|
|
|
|
|
|
|
|
|
// 做全量更新时,上好写锁,不允许读取数据。 读取数据时,需要走读锁
|
|
|
|
|
private static final ReentrantReadWriteLock READ_WRITE_LOCK = new ReentrantReadWriteLock();
|
|
|
|
|
private static final ReentrantReadWriteLock.WriteLock WRITE_LOCK = READ_WRITE_LOCK.writeLock();
|
|
|
|
|
private static final ReentrantReadWriteLock.ReadLock READ_LOCK = READ_WRITE_LOCK.readLock();
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void afterPropertiesSet() throws Exception {
|
|
|
|
|
// scheduleAtFixedRate 每次间隔3s,但是任务的执行时间,也会算到这3s内。
|
|
|
|
|
// scheduleWithFixedDelay 每次间隔3s,等待上个任务完成后,间隔3s再执行下次任务。
|
|
|
|
|
AIR_POOL.scheduleWithFixedDelay(() -> {
|
|
|
|
|
// 这里做全量更新
|
|
|
|
|
// 1、查询数据库中的全部数据 TODO 后面全量查询数据库
|
|
|
|
|
Map<Long,Air> allData = new HashMap<>();
|
|
|
|
|
// 2、同步到JVM缓存中。
|
|
|
|
|
writeAll(allData);
|
|
|
|
|
},0,3, TimeUnit.SECONDS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 全量更新 (数据体量比较小,咱们采用全量更新。 如果数据体量比较大,采用增量更新,增量更新,需要考虑多个JVM之间的数据同步,MQ的广播机制去玩)
|
|
|
|
|
private void writeAll(Map<Long, Air> allData) {
|
|
|
|
|
// 获取写锁
|
|
|
|
|
WRITE_LOCK.lock();
|
|
|
|
|
try{
|
|
|
|
|
// 清除缓存全部数据
|
|
|
|
|
AIR_CACHE.clear();
|
|
|
|
|
// 全量更新
|
|
|
|
|
AIR_CACHE.putAll(allData);
|
|
|
|
|
}finally {
|
|
|
|
|
WRITE_LOCK.unlock();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 对外提供查询功能
|
|
|
|
|
public Air getAirById(Long id){
|
|
|
|
|
if(id == null) return null;
|
|
|
|
|
boolean b = READ_LOCK.tryLock();
|
|
|
|
|
if(!b){
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
try{
|
|
|
|
|
Air air = AIR_CACHE.get(id);
|
|
|
|
|
return air;
|
|
|
|
|
}catch (Exception e){
|
|
|
|
|
return null;
|
|
|
|
|
}finally{
|
|
|
|
|
READ_LOCK.unlock();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|