2020年5月29日 14:46:26更新
无意间看到了大家对这个帖子访问的挺多,看来大家都有遇到这种问题,之前的方法只针对小规模小并发的项目使用,这几天我抽个时间讲个通过缓存或者mysql定时任务来进行数据更新的方法,应该比较可靠
其实做开发都有这么一个体验,就是日常工作的时候,面对一些功能总是会有一些脑袋抽风的事情,也许明明调用一个很简单的方法就能搞定的事情,硬是绕了一个大圈实现。
这里我就遇到了一个需求,就是说一个模块,用户点击后生成了一个临时体验权给用户体验。体验时间为二十分钟,二十分钟结束后自动关闭权限。
在不涉及高并发和大流量的前提下,我之前的设计是增加了一个定时调度方法,每秒进行一次刷新,将到期的用户权限关闭。这方法可以是可以但是每秒钟都会有一个调度方法被执行,说实话挺浪费资源的。
其实我们可以直接可以new一个线程用线程休眠来实现对应功能的。大致Demo如下:
模拟方法
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 定时方法回调
* @author Administrator
*
*/
public class Demo1 {
public static String s(int i) {
String s=i+"号开始时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
new Thread() {
public void run() {
try {
sleep(5000);
System.err.println(i+"号程执行时间"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
return s;
}
}
public class Demo {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 3; i++) {
Thread.sleep(2000);
System.out.println(Demo1.s(i));
}
}
}
当然,有人可能会说:“你不误导别人吗?若出现大量访问你疯狂生成新线程系统崩了怎么办?”
嗯!好问题。所以我们可以选择使用线程池来进行优化该Demo
已知的线程池有以下几类
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
毕竟项目不大,且我也不知道用户使用峰值,所以我们这里就采用第一种吧。
优化后的调用方法
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 定时方法回调
* @author Administrator
*
*/
public class Demo1 {
static ExecutorService fixedThreadPool = Executors.newCachedThreadPool();
public static String s(int i) {
String s=i+"号开始时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
System.err.println(i+"号程执行时间"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
return s;
}
}
以上,就是执行一个方法后定时再执行另一个方法的大致Demo。
还有可以使用定时调度方法,我没有试过所以就不上了,贴个地址也许能用得上:https://www.cnblogs.com/0201zcr/p/4703061.html