MediaCacheLocal.java 2.61 KB
package com.yanzuoguang.media;

import com.yanzuoguang.util.helper.JsonHelper;

import java.util.HashMap;
import java.util.Map;

/**
 * 本地缓存实现
 *
 * @author 颜佐光
 */
public class MediaCacheLocal implements MediaCacheBase {

    private Map<String, MapLock> mapLock = new HashMap<String, MapLock>();

    /**
     * 获取缓存是否正在执行
     *
     * @param req      需要运行的请求参数
     * @param runnable 当没有运行时,需要执行的函数
     * @return
     */
    @Override
    public MediaResVo start(MediaReqVo req, Runnable runnable) {
        // 获取锁
        MapLock mapLock = getMapLock(req);
        // 锁定缓存对象,防止多人执行
        synchronized (mapLock) {
            // 读取历史缓存
            MediaResVo tempRes = mapLock.res;
            // 写入结果到缓存
            mapLock.res = JsonHelper.to(req, MediaResVo.class);
            // 判断历史缓存的次数,确定是否执行
            if (tempRes == null || tempRes.getCount() < 1) {
                // 执行时,会开启线程下载视频,并转换为截图文件
                runnable.run();
            }
            // 返回缓存中的结果
            return mapLock.res;
        }
    }

    /**
     * 获取缓存是否正在运行
     *
     * @param req
     * @return
     */
    @Override
    public MediaResVo get(MediaReqVo req) {
        // 获取锁
        MapLock mapLock = getMapLock(req);
        // 锁定缓存对象,防止多人执行
        synchronized (mapLock) {
            return mapLock.res;
        }
    }

    /**
     * 写入处理结果到缓存中
     *
     * @param res
     */
    @Override
    public void sub(MediaResVo res) {
        // 获取锁
        MapLock mapLock = getMapLock(res);
        // 锁定缓存对象,防止多人执行
        synchronized (mapLock) {
            mapLock.res.subCount();
        }
    }

    /**
     * 锁定临时文件,防止被人修改
     *
     * @param req
     * @param runnable
     */
    @Override
    public void lockTempFile(MediaReqVo req, Runnable runnable) {
        MapLock lock = getMapLock(req);
        synchronized (lock.lockTemp) {
            runnable.run();
        }
    }

    private MapLock getMapLock(MediaReqVo req) {
        synchronized (mapLock) {
            MapLock lock = this.mapLock.get(req.getUrl());
            if (lock == null) {
                lock = new MapLock();
                this.mapLock.put(req.getUrl(), lock);
            }
            return lock;
        }
    }

    private static class MapLock {
        Object lockTemp = new Object();
        MediaResVo res;
    }
}