我正在寻求有关一般方法的帮助。
我已经编写了一些java代码,用于在buttonclick上查看我的邮箱中的未读邮件。
现在我想让这段代码永久在后台运行,并且每2分钟检查一次我的邮箱。
糟糕的主意:
while(true)
{
checkMails();
Thread.sleep(120000);
}
图形界面的其余部分显然会冻结,所以我猜想必须在线程中发挥一些魔力。
怎么能实现呢?
答案 0 :(得分:4)
使用javax.swing.Timer
或SwingWorker
,虽然后者在这种情况下有点矫枉过正。
如果此任务不修改任何Swing组件,那么为什么不直接生成一个单独的线程
Thread t = new Thread(new Runnable(){
@Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
//do stuff
try{
Thread.sleep(120000);
}catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
}
});
t.start();
重要的是要注意,你可能想要使用boolean
来确保线程只创建一次,因为每次点击按钮都会产生一个新线程的可能性,这可能不是你想要什么。
答案 1 :(得分:2)
为什么不直接生成一个单独的线程来处理checkMails()
并执行你已经拥有的操作。更新GUI时要小心。
Thread thread = new Thread(new Runnable() {
public void run() {
while (true) {
checkMails();
Thread.sleep(120000);
}
}
});
编辑:也许您应该在想要停止检查新邮件的情况下(无论出于何种原因)在某处添加支票。你也得打电话给thread.start();
答案 2 :(得分:1)
使用javax.swing.Timer
。像这样:
int delay = 120000;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
checkMails();
}
};
new Timer(delay, taskPerformer).start();
答案 3 :(得分:1)
您需要使用线程来解决此问题。线程就像多任务一样。
Thread t = new Thread(){
public void run(){
//do job
}
}
t.start(); //starts the thread
要结束线程,您需要某种停止条件
public boolean run = false;
Thread t = new Thread(){
public void run(){
while(run)
//do job
}
}
public void startThread(){
t.start(); //starts the thread
}
另见:
Thread.stop()
将杀死该线程,但这非常糟糕。例如,假设您正在写入数组
for(int i = 0; i < myAr.length; i++)
myAr[i] = getStuff(i);
在i = 5
,Thread.stop()
被调用。现在你的程序认为一切都很好,事实上,它不是!
要杀死该主题,请将run
设置为false
。 run
是我在第二个例子中展示的boolean
。另一个选项是创建Thread
的子类(不仅仅是在行覆盖方法中)并创建方法halt()
(stop
是最终的)。 halt()
会将run
设为false。 run
仍然是全球boolean
。
这是一个例子。
public class MyThread extends Thread {
public boolean run = true;
public void run(){
run = true;
while(run)
doStuff();
}
public void halt(){
run = false;
}
}
您需要注意两个线程不会同时修改同一个对象,这就像将对象转换为随机数生成器一样:/
现在你已经获得了线程的力量,明智地使用它,为了善恶而不是邪恶!走吧,保持线程安全。
答案 4 :(得分:0)
一些想法:
1)创建一个定期触发的java.util.Timer
,检查邮箱中的消息并使用SwingUtilities#invokeLater
更新GUI;
2)创建一个计时器(java.util.Timer
或javax.swing.Timer
),计划javax.swing.SwingWorker
以检查邮箱并更新GUI。
3)创建一个检查邮箱的Thread
,使用SwingUtilities#invokeLater
更新GUI并休眠一段时间;
我会使用1或2,因为如果你需要取消任务,你可以停止计时器。
答案 5 :(得分:-1)
如果您需要在完成checkMails()方法后更新UI,则显然需要使用 EDT 。
您正在寻找异步(另一种是同步)方式。
当然,您正在寻找SwingUtilities.html#invokeLater(java.lang.Runnable)
据我所知,这是为Swing做背景任务的正确方法。
Runnable checkMail = new Runnable() {
public void run() {
while(true) {
checkMails();
Thread.sleep(120000); //but this is very naive approach to use sleep, consider using timer ;)
}
}
};
SwingUtilities.invokeLater(checkMail);
invokeLater(Runnable doRun):使得doRun.run()在AWT事件派发线程上异步执行。
和
invokeAndWait(Runnable doRun):使得doRun.run()在AWT事件派发线程上同步执行。