即使在Websphere中停止应用程序后,线程仍会继续运行

我有一个长期运行的线程,使用org.springframework.scheduling.commonj.WorkManagerTaskExecutor和Spring创建,并在Websphere Application Server 8中运行。

问题是即使应用程序已停止,此线程仍会继续运行。 该线程也需要停止,但它没有发生。 我甚至尝试使用Thread.currentThread().isInterrupted()来检查当前线程是否被中断但它总是返回false 。 所以没有办法通过我的代码知道线程应该继续运行还是停止。

这是我对WorkManagerTaskExecutor的弹簧配置:

    

线程正在以这种方式执行:

 Thread t = new EmailReaderThread(email); workManagerTaskExecutor.execute(t); 
  • 我错过了什么?
  • 我能做什么,每当应用程序停止时,应用程序的线程(应用程序生成的线程)也会停止?

我认为这不被视为非托管线程,因为我使用适当的WorkManager注册线程,容器由JNDI作为资源公开。

更新:这是创建线程的代码。

 @Service @Transactional public class SmsServiceHypermedia implements SmsService { @Autowired private WorkManagerTaskExecutor workManagerTaskExecutor; public SmsServiceHypermedia() { createEmailReaderThread(); } private void createEmailReaderThread() { log.debug("Generating Email Reader Threads..."); Email email = getDefaultEmail(); //obtain the default Email object, not important for the problem. EmailReaderThread r = new EmailReaderThread(email); workManagerTaskExecutor.execute(r); } private class EmailReaderThread extends Thread { private Email email; private Session session; public EmailReaderThread(Email email) { this.email = email; } @Override public void run() { readEmails(); } public void readEmails() { final long delay = 30 * 1000; //delay between message poll. log.debug("Starting to read emails for email: " + email.getAddress()); while(!Thread.currentThread().isInterrupted()) { try { log.debug("Current session: " + session); Store store = session.getStore(); log.debug("Connecting using session: " + session); store.connect(); Folder inbox = store.getFolder("INBOX"); inbox.open(Folder.READ_WRITE); javax.mail.Message[] messages = inbox.search( new FlagTerm(new Flags(Flags.Flag.SEEN), false)); for (javax.mail.Message message : messages) { //Do something with the message } inbox.close(true); store.close(); block(delay); } catch (Exception e) { throw new RuntimeException(e); } } } //I know this could be implemented by calling Thread.sleep() is just that I ran out of options so I also tried it this way. private void block(long millis) { final long endTime = System.currentTimeMillis() + millis; log.debug("Blocking for this amount of time: " + millis + " ms"); while (System.currentTimeMillis() < endTime) { } log.debug("End of blocking."); } } } 

根据CommonJ规范,只有当isDaemon()方法返回true时,WorkManager才会尝试停止执行Work。 非守护进程的工作预计会短暂运行,因此不需要停止它们。

问题是默认情况下,Spring使用的Work实现的isDaemon()方法(实际上包装了Runnable)返回false。 您可以通过使Runnable实现SchedulingAwareRunnable来更改它。

但是,这还不够。 如果WorkManager决定停止工作,那么它将调用Work#release(),并且工作本身负责确保它停止。 特别是,WorkManager不会尝试中断正在执行Work的线程(因为这不是停止线程的可靠方法)。 问题是Spring使用的Work实现对release()方法有一个空的实现,因此你不能使用该function。

总结一下:如果你想使用Spring,确保执行停止的唯一方法就是为它设计自己的机制。

请注意,使用SchedulingAwareRunnable仍然很有趣,因为这将避免WebSphere的线程监视器(关于挂起线程)生成的警告。