计划的执行者服务不工作

Scheduled Executor Service isn't working

我想要每天(每 24 小时)运行 执行特定任务。我使用了计划的执行程序服务,但在我用 20 秒测试它以查看任务是否 运行 后,它没有。难道我做错了什么? 任何帮助将不胜感激。

ScheduledExecutorService scheduler = Executors
            .newScheduledThreadPool(1);

    scheduler.scheduleWithFixedDelay(new TimerTask() {
        public void run() {
            ArrayList<Integer> people = new ArrayList<Integer>();
            try {
                shelf.g.setOverdue();
                for (int i = 1; i < 1000; i++) {
                    if (shelf.book[i] != null
                            && shelf.book[i].checkedOut != null) {
                        if (shelf.book[i].overdue == true) {
                            for (int i2 = 0; i < 600; i++) {
                                if (account.person[i] == null) {
                                    account.person[i] = new account();
                                }
                                if (account.person[i2].name
                                        .equalsIgnoreCase(shelf.book[i].personName)) {
                                    people.add(i2);
                                }
                            }
                        }
                    }
                }
                Set<Integer> s = new LinkedHashSet<Integer>(people);
                people = new ArrayList<Integer>(s);
                ArrayList<String> books = new ArrayList<String>();

                Properties props = new Properties();
                Session session = Session.getInstance(props);
                MimeMessage msg = new MimeMessage(session);
                Transport t = null;
                Address from = new InternetAddress(
                        "LGCCLibrary42@gmail.com", "LGCC Library");
                for (int i = 0; i < people.size(); i++) {
                    for (int i2 = 1; i2 < 1000; i2++) {
                        if (shelf.book[i2] != null
                                && shelf.book[i2].checkedOut != null) {
                            if (shelf.book[i2].overdue == true) {
                                if (account.person[people.get(i)].name
                                        .equalsIgnoreCase(shelf.book[i2].personName)) {

                                    books.add("Book " + i2 + " - " + shelf.book[i2].bookName
                                            + "\n");

                                }
                            }
                        }
                    }
                    String thePerson = account.person[people.get(i)].name;
                    Address to = new InternetAddress(account.person[people
                            .get(i)].eMail);

                    msg.setText(thePerson
                            + " , you have the following books overdue"
                            + "\n" + books.toString().replace("[", "").replace("]", ""));
                    msg.setFrom(from);
                    msg.setRecipient(Message.RecipientType.TO, to);
                    msg.setSubject("LGCC library overdue books");

                    t = session.getTransport("smtps");
                    t.connect("smtp.gmail.com", "LGCCLibrary42", "4JesusChrist");
                    t.sendMessage(msg, msg.getAllRecipients());
                    books.clear();
                }
                t.close();

            } catch (UnsupportedEncodingException ex) {
                // TODO Auto-generated catch block
                JOptionPane.showMessageDialog(null, "Something went wrong",
                        "Alert", JOptionPane.ERROR_MESSAGE);


            } catch (AddressException ex) {
                // TODO Auto-generated catch block
                JOptionPane.showMessageDialog(null, "Something went wrong",
                        "Alert", JOptionPane.ERROR_MESSAGE);

            } catch (MessagingException ex) {
                // TODO Auto-generated catch block
                JOptionPane.showMessageDialog(null, "Something went wrong",
                        "Alert", JOptionPane.ERROR_MESSAGE);

            }
        }
    }, 0, 24, TimeUnit.HOURS);

正如@JeremeyFarrell 所说,使用 Runnable 而不是 TimerTask;使用 TimerTask.

没有任何功能或好处

我已经简化了您的代码,它可以正常工作:

ScheduledExecutorService scheduler = Executors
        .newScheduledThreadPool(1);

scheduler.scheduleWithFixedDelay(new Runnable() {
    public void run() {
        System.out.println("Do something useful");
    }
}, 0, 1, TimeUnit.SECONDS);

您的问题最可能的原因可以在 scheduleWithFixedDelay 的 Javadoc 中找到:

If any execution of the task encounters an exception, subsequent executions are suppressed.

您可能有一个异常,可能是 RuntimeException(例如 NullPointerException),它停止了进一步的调用。

解决这个问题的一种方法是捕获所有异常并记录它们。

scheduler.scheduleWithFixedDelay(new Runnable() {
    public void run() {
        try {
            doTheRealWork(); // Such as "sendEmail()"
        } catch (Exception e) {
            e.printStackTrace(); // Or better, use next line if you have configured a logger:
            logger.error("Exception in scheduled e-mail task", e);
        }
    }
}, 0, 1, TimeUnit.SECONDS);

(注意:当然,一旦您对事情按预期工作感到满意,请将 1, TimeUnit.SECONDS 替换为 24, TimeUnit.HOURS

需要指出的几点:

  • 您从 UI 线程以外的线程调用 JOptionPane.showMessageDialog。 Swing 不支持从除主 UI 线程之外的任何线程执行 UI 工作;如果你仍然这样做,你可以获得各种竞争条件。
  • 在任何情况下,即使这不是问题,您也会在用户交互时阻塞计划线程;在您的应用程序可以继续之前,必须有人按 "OK"
  • 但这不会导致你的问题。