Tôi có một thread chạy dài mà được tạo ra sử dụng org.springframework.scheduling.commonj.WorkManagerTaskExecutor
với mùa xuân và đang chạy trong Websphere Application Server 8.Chủ đề tiếp tục chạy ngay cả sau khi ứng dụng đã được dừng lại ở Websphere
Vấn đề là chủ đề này tiếp tục chạy ngay cả nếu ứng dụng đã bị dừng. Chủ đề đó cần được dừng lại nhưng nó không xảy ra. Tôi thậm chí đã cố gắng sử dụng Thread.currentThread().isInterrupted()
để kiểm tra xem chuỗi hiện tại có bị gián đoạn hay không nhưng nó luôn trả về false
. Vì vậy, không có cách nào để biết thông qua mã của tôi nếu Chủ đề nên tiếp tục chạy hoặc dừng lại.
Đây là cấu hình mùa xuân của tôi cho WorkManagerTaskExecutor:
<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
<property name="workManagerName" value="wm/default" />
</bean>
Các chủ đề đang được thực hiện theo cách này:
Thread t = new EmailReaderThread(email);
workManagerTaskExecutor.execute(t);
- tôi thiếu gì?
- Tôi có thể làm gì để bất cứ khi nào ứng dụng bị dừng, luồng của ứng dụng (các chủ đề được tạo ra bởi ứng dụng) cũng dừng lại?
Tôi nghĩ rằng đây không được coi là một chuỗi không được quản lý vì tôi đang đăng ký chủ đề bằng cách sử dụng WorkManager thích hợp mà vùng chứa hiển thị dưới dạng tài nguyên bởi JNDI.
Cập nhật: Đây là mã tạo chủ đề.
@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.");
}
}
}
Bạn không nên chuyển Runnable sang WorkManagerTaskExecutor.execute (tác vụ WorkManagerTaskExecutor) thay vì một Thread? – Hyangelo
Một chủ đề thực hiện Runnable như vậy là một Runnable. Tôi nghĩ đó không phải là vấn đề. –
các nhà thực thi không bao giờ gọi phương thức 'start()' của một chuỗi được truyền vào (chỉ có 'run()') để bạn có thể sử dụng một runnable bình thường (không phải là một luồng) –