I have a long running thread which is created using org.springframework.scheduling.commonj.WorkManagerTaskExecutor
with Spring and is running in Websphere Application Server 8.
The problem is that this thread keeps running even if the application has been stopped. That thread needs to be stopped too but it is not happening. I even tried to use Thread.currentThread().isInterrupted()
to check if the current thread was interrupted but it always returns false
. So there is no way to know through my code if the Thread should keep running or stop.
This is my spring configuration for the WorkManagerTaskExecutor:
<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
<property name="workManagerName" value="wm/default" />
</bean>
The thread is being executed this way:
Thread t = new EmailReaderThread(email);
workManagerTaskExecutor.execute(t);
- What am I missing?
- What can I do so that whenever the application is stopped the application's thread (threads that were generated by the application) stops too?
I think this is not considered an unmanaged thread because I am registering the thread using the appropriate WorkManager which the container exposes as a resource by JNDI.
Update: Here is the code which creates the Thread.
@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.");
}
}
}
start()
method of a passed in thread (only therun()
) so you might as well use a normal runnable (not a thread) – Oisin