/**
* 下载控制器
* 阻塞集中式下载 防止系统崩溃
* 使用定时过期的缓存锁实现
* 每10分钟只能下载一次
**/
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class DownloadControl {
private static final String CACHE_KEY = "DOWNLOAD";
/**
* 下载权限保存地点
*
*/
private static final Cache<String, String> cache = CacheBuilder.newBuilder()
.initialCapacity(1)
.concurrencyLevel(1)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
/**
* 尝试获取下载权限 未获取到权限
*/
public static synchronized boolean notGetPermission() {
return !tryGetPermission();
}
private static synchronized boolean tryGetPermission() {
String hasLock = cache.getIfPresent(CACHE_KEY);
if (hasLock == null) {
cache.put(CACHE_KEY, "1");
return true;
}
return false;
}
/**
* 重置下载权限
*/
public static synchronized void resetPermission() {
cache.invalidate(CACHE_KEY);
}
}
在下载方法中使用:
if(DownloadControl.notGetPermission()){
request.setAttribute(ReturnConstant.MEMO, "当前下载队列满!请稍后重试。");
return mapping.findForward(ReturnConstant.ERROR);
}
try{
下载代码
} catch (Exception e) {
String memo = "下载失败,请稍后再试 ···";
log.info("异常:{} ", memo, e);
}finally {
DownloadControl.resetPermission();
}
测试:
public class DownloadControlTest {
@Test
public void hasPermission() throws InterruptedException {
//模拟并发
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
Thread.sleep(500);
final int finalI = i;
executorService.execute(new Runnable() {
@Override
public void run() {
try {
boolean res = DownloadControl.notGetPermission();
System.out.println(finalI + " " + res + " " + DateUtil.getNow());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
@Test
public void resetPermission() throws InterruptedException {
//模拟并发
ExecutorService executorService = Executors.newCachedThreadPool();
Thread.sleep(1000L);
executorService.execute(new Runnable() {
@Override
public void run() {
try {
boolean res = DownloadControl.notGetPermission();
System.out.println(res + " " + DateUtil.getNow());
} catch (Exception e) {
e.printStackTrace();
}
DownloadControl.resetPermission();
}
});
Thread.sleep(1000L);
executorService.execute(new Runnable() {
@Override
public void run() {
try {
boolean res = DownloadControl.notGetPermission();
System.out.println(res + " " + DateUtil.getNow());
} catch (Exception e) {
e.printStackTrace();
}
}
});
Thread.sleep(1000L);
executorService.execute(new Runnable() {
@Override
public void run() {
try {
boolean res = DownloadControl.notGetPermission();
System.out.println(res + " " + DateUtil.getNow());
} catch (Exception e) {
e.printStackTrace();
}
}
}); }
}