通过 ZSet 实现定时任务的思路是,将定时任务存放到 ZSet 集合中,并且将过期时间存储到 ZSet 的 Score 字段中,然后通过一个无线循环来判断当前时间内是否有需要执行的定时任务,如果有则进行执行,具体实现代码如下:
import redisclientsjedisJedis;
import utilsJedisUtils;
import javatimeInstant;
import javautilSet;
public class DelayQueueExample {
private static final String _KEY = "DelayQueueExample";
public static void main(String[] args) throws InterruptedException {
Jedis jedis = JedisUtilsgetJedis();
// 30s 后执行
long delayTime = Instantnow()plusSeconds(30)getEpochSecond();
jediszadd(_KEY, delayTime, "order_1");
// 继续添加测试数据
jediszadd(_KEY, Instantnow()plusSeconds(2)getEpochSecond(), "order_2");
jediszadd(_KEY, Instantnow()plusSeconds(2)getEpochSecond(), "order_3");
jediszadd(_KEY, Instantnow()plusSeconds(7)getEpochSecond(), "order_4");
jediszadd(_KEY, Instantnow()plusSeconds(10)getEpochSecond(), "order_5");
// 开启定时任务队列
doDelayQueue(jedis);
}
/
定时任务队列消费
@param jedis Redis 客户端
/
public static void doDelayQueue(Jedis jedis) throws InterruptedException {
while (true) {
// 当前时间
Instant nowInstant = Instantnow();
long lastSecond = nowInstantplusSeconds(-1)getEpochSecond();
// 上一秒时间
long nowSecond = nowInstantgetEpochSecond();
// 查询当前时间的所有任务
Set data = jediszrangeByScore(_KEY, lastSecond, nowSecond);
for (String item : data) {
// 消费任务
Systemoutprintln("消费:" + item);
}
// 删除已经执行的任务
jediszremrangeByScore(_KEY, lastSecond, nowSecond);
Threadsleep(1000); // 每秒查询一次
}
}
}
登录后复制

2、键空间通知
我们可以通过 Redis 的键空间通知来实现定时任务,它的实现思路是给所有的定时任务设置一个过期时间,等到了过期之后,我们通过订阅过期消息就能感知到定时任务需要被执行了,此时我们执行定时任务即可。
默认情况下 Redis 是不开启键空间通知的,需要我们通过 config set notify-keyspace-events Ex 的命令手动开启,开启之后定时任务的代码如下
报错原因: 强行转换普通类为一个XxxListener类,导致错误;
修改方法:
让普通的类chuang 去实现ActionListener, TextListener 接口public class chuang implements ActionListener, TextListener {
}
其他建议: 代码太乱,代码不规范,建议修改
运行测试:
参考代码如下:
import javaawt;import javaawtevent;
//TestFrame继承自Frame实现了 ActionListener, TextListener接口
public class TestFrame extends Frame implements ActionListener, TextListener {
private Button button;
private TextField text;
public TestFrame() {
button=new Button("save");
buttonsetEnabled(false);
buttonaddActionListener(this);
text = new TextField(20);
textaddTextListener(this);
//普通的面板,设置为流布局水平间距10,垂直间距30
Panel pane=new Panel(new FlowLayout(FlowLayoutCENTER, 10, 30));
paneadd(text);
paneadd(button);
add(pane);
setTitle("窗口Demo");
setSize(290, 120);
setLocationRelativeTo(null);//窗口居中
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {//点击关闭按钮后的事件处理
Systemexit(0);
}
});
}
public static void main(String[] args) {
new TestFrame()setVisible(true);;
}
//文本框发生变化后的事件处理
@Override
public void textValueChanged(TextEvent e) {
//当文本框里面没有字符或者全是空格, 那么设置按钮不可点击
if(!textgetText()trim()isEmpty()){
buttonsetEnabled(true);
}else{
buttonsetEnabled(false);
}
}
//点击按钮后的事件处理
@Override
public void actionPerformed(ActionEvent e) {
buttonsetEnabled(false);
Systemoutprintln(textgetText());//打印出来
}
}位置问题的话你加一句 jpsetLayout(null); 把布局管理器去掉就好了,还有一个问题就是你现在把组件又加到jframe又加到jpanel没必要,只要加到panel再把panel加到frame就可以了
jfgetContentPane()add(jl1); 这类的都可以去掉1、一般的解决方法大多是在数据库连接字符串中增加“autoReconnect=true ”选项。但是这只对mysql4以前的版本有效。在最新的mysql中是无效的。其实要解决这个问题也有一个简单的方法,就是修改mysql的启动参数。缺省情况下mysql的timeout时间是28800秒,正好是8小时,增加一个0就可以了。
同理也可以在" myini"文件中增加此参数。
mysqld-nt --default-table-type=innodb --interactive_timeout=288000
2、从根源入手,设置mysql的wait_timeout为31536000(一年)。
mysql> show variables;
| wait_timeout | 28800
| interactive_timeout | 28800
" myini"文件中修改此参数
[mysqld]
wait_timeout=31536000
interactive_timeout=31536000
重启服务,OK!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)