2011-12-28 7 views
7

durdu sonra bile çalışmaya devam 8.Konu uygulamam Bahar ile <code>org.springframework.scheduling.commonj.WorkManagerTaskExecutor</code> kullanılarak oluşturulur ve Websphere Application Server çalıştıran bir uzun koşu ipliği var Websphere

sorun Konuyu bile çalıştıran tutmasıdır Uygulama durdurulduysa. Bu iş parçacığının da durdurulması gerekiyor ama bu gerçekleşmiyor. Hatta şimdiki parçacığı kesildi olmadığını kontrol etmek için Thread.currentThread().isInterrupted() kullanmaya çalıştı ama her zaman false döndürür. Bu yüzden eğer iş parçacığı çalışmaya devam etmeli veya durmalıysa, kodumdan bilmenin bir yolu yoktur.

Bu WorkManagerTaskExecutor benim bahar yapılandırmasıdır:

iplik bu şekilde yürütülmektedir
<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor"> 
     <property name="workManagerName" value="wm/default" /> 
</bean> 

:

Thread t = new EmailReaderThread(email); 
workManagerTaskExecutor.execute(t); 
  • ben eksik? Uygulama uygulamanın iş parçacığı durdurulur zaman (uygulanmasıyla üretilmiş olan konu) çok durur, böylece
  • Ne yapabilirim?

ben konteyner JNDI tarafından bir kaynak olarak ortaya Uygun WorkManager kullanılarak iplik kayıt ediyorum çünkü bu yönetilmeyen iş parçacığı olarak kabul edilmez düşünüyorum.

Güncelleme: İşte iş parçacığı oluşturan kod.

@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."); 
     } 
    } 
} 
+0

Bir İş Parçacığı yerine WorkManagerTaskExecutor.execute (WorkManagerTaskExecutor görevi) için bir Runnable geçmemelisiniz? – Hyangelo

+0

A Thread Runnable'ı uygular, bu nedenle Runnable'dır. Bence sorun bu değil. –

+0

executors 'start()' parçacığı (sadece 'koşmak()') geçirilen bu yüzden siz de normal bir çalıştırılabilir (bir iş parçacığı) kullanabileceği bir –

cevap

6

CommonJWorkManagerTaskExecutor özellikleri uyarınca, bir WorkManager onun isDaemon() metodu doğru döndürür, yalnızca bir çalışma yürütme durdurmak için çalışacaktır. Non-daemon Works'ün kısa süreli çalışması beklenir, böylece durdurulmaları gerekmez.

Sorun, varsayılan olarak, Yay tarafından kullanılan İş uygulamasının isDaemon() yönteminin (ve aslında Runnable'ı sararlayan) yanlış olması durumunda döndürüldüğüdür. Runnable uygulamanızı SchedulingAwareRunnable yaparak değiştirebilirsiniz.

Ancak, bu yeterli değildir. WorkManager Work durdurmaya karar verirse, o zaman Çalışma # salınımını (arayacak) ve durana emin olmak için Work kendi sorumluluğundadır. Özellikle, WorkManager (yani bir iş parçacığı durdurmak için güvenilir bir yol olmadığı için) Çalışma yürütülürken iplik kesmek denemez. Sorun, Spring tarafından kullanılan İş uygulamasının, bu özelliği kullanamayacağınız şekilde release() yöntemi için boş bir uygulamaya sahip olmasıdır.

Özetlemek gerekirse: Spring'i kullanmak isterseniz, yürütmenin durdurulduğundan emin olmanın tek yolu, bunun için kendi mekanizmanızı tasarlamaktır.

SchedulingAwareRunnable'ı kullanmak hala ilginçtir, çünkü bu WebSphere'ın iş parçacığı monitörü tarafından oluşturulan uyarılardan (asılı iplikler hakkında) kaçınacaktır.

+0

WorkManagerTaskExecutor'ın kaynak kodunu kontrol ettim ve yazdıklarınız mükemmel bir anlam ifade ediyor. Teşekkür ederim. Kendi uygulamanızla birlikte "release()" i geçersiz kılamanın çok kötü olduğunu düşünüyorum. –

İlgili konular