我正在寻求有关一般方法的帮助。
我已经编写了一些 java 代码来检查我的邮箱是否有按钮单击上的未读邮件。
现在我希望这段代码在后台永久运行,每 2 分钟检查一次我的邮箱。
馊主意:
while(true)
{
checkMails();
Thread.sleep(120000);
}
图形界面的其余部分显然冻结了,所以我想线程必须发生一些魔法。
这怎么可能实现?
我正在寻求有关一般方法的帮助。
我已经编写了一些 java 代码来检查我的邮箱是否有按钮单击上的未读邮件。
现在我希望这段代码在后台永久运行,每 2 分钟检查一次我的邮箱。
馊主意:
while(true)
{
checkMails();
Thread.sleep(120000);
}
图形界面的其余部分显然冻结了,所以我想线程必须发生一些魔法。
这怎么可能实现?
要么使用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();
请务必注意,您可能希望使用 aboolean
来确保线程只创建一次,因为每次单击按钮时都有可能产生一个新线程,这可能不是您想要的。
您为什么不生成一个单独的线程来处理checkMails()
并执行您已经拥有的操作。更新 GUI 时要小心。
Thread thread = new Thread(new Runnable() {
public void run() {
while (true) {
checkMails();
Thread.sleep(120000);
}
}
});
编辑:如果您想停止检查新邮件(无论出于何种原因),也许您应该在某处添加检查。你也得打电话thread.start();
使用javax.swing.Timer
. 像这样的东西:
int delay = 120000;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
checkMails();
}
};
new Timer(delay, taskPerformer).start();
你需要使用线程来解决这个问题。线程就像多任务处理。
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
为假。run
仍将是一个全球性的boolean
.
这是一个例子。
public class MyThread extends Thread {
public boolean run = true;
public void run(){
run = true;
while(run)
doStuff();
}
public void halt(){
run = false;
}
}
您需要注意两个线程不会同时修改同一个对象,这就像将一个对象变成一个随机数生成器:/
既然您已经获得了线的力量,请明智地使用它,为善而不是为恶!继续前进并保持线程安全。
一些想法:
1)创建一个java.util.Timer
定期触发,检查邮箱中的消息并使用更新GUI SwingUtilities#invokeLater
;
2) 创建一个计时器(java.util.Timer
或javax.swing.Timer
),用于安排 ajavax.swing.SwingWorker
来检查邮箱和更新 GUI。
3)创建一个Thread
检查邮箱,更新GUI使用SwingUtilities#invokeLater
并休眠一段时间;
我会使用 1 或 2,因为如果您需要取消任务,您可以停止计时器。
显然,如果在完成 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 事件调度线程上同步执行。