org.springframework.scheduling.commonj.WorkManagerTaskExecutor
Spring を使用して作成され、Websphere Application Server 8 で実行されている実行時間の長いスレッドがあります。
問題は、アプリケーションが停止されても、このスレッドが実行され続けることです。そのスレッドも停止する必要がありますが、それは起こっていません。Thread.currentThread().isInterrupted()
現在のスレッドが中断されたかどうかを確認するために使用しようとしまし たが、常に返されますfalse
。そのため、スレッドを実行し続けるか停止するかをコードから知る方法はありません。
これは、WorkManagerTaskExecutor の私の春の構成です。
<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
<property name="workManagerName" value="wm/default" />
</bean>
スレッドは次のように実行されています。
Thread t = new EmailReaderThread(email);
workManagerTaskExecutor.execute(t);
- 私は何が欠けていますか?
- アプリケーションが停止するたびにアプリケーションのスレッド (アプリケーションによって生成されたスレッド) も停止するようにするにはどうすればよいですか?
コンテナーが JNDI によってリソースとして公開する適切なWorkManagerを使用してスレッドを登録しているため、これはアンマネージド スレッドとは見なされないと思います。
更新: スレッドを作成するコードは次のとおりです。
@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.");
}
}
}