2009-05-12 19 views
24

Próbuję uzyskać uchwyt na temat wykonywania wątków w aplikacji Java, która używa Spring do zarządzania transakcjami. Znalazłem sekcji TaskExecutor w Spring documentation, a ThreadPoolTaskExecutor wygląda tak, jakby pasował do moich potrzeb;Jakieś dobre nawlekanie za pomocą przykładów TaskExecutor?

ThreadPoolTaskExecutor

Implementacja ta może być używana tylko w środowisku Java 5, ale jest również najczęściej używany jeden w tym środowisku. Ujawnia właściwości komponentu bean do konfigurowania obiektu java.util.concurrent.ThreadPoolExecutor i opakowuje go w TaskExecutor. Jeśli potrzebujesz czegoś zaawansowanego, takiego jak ScheduledThreadPoolExecutor, zalecane jest użycie ConcurrentTaskExecutor.

Jednak nie mam pojęcia, jak go użyć. Szukałem dobrych przykładów przez jakiś czas, bez powodzenia. Jeśli ktokolwiek może mi pomóc, będę wdzięczny.

Odpowiedz

33

To całkiem proste. Chodzi o to, że masz obiekt executora, który jest fasolą, który jest przekazywany do dowolnego obiektu, który chce wystrzelić nowe zadanie (w nowym wątku). Fajną rzeczą jest to, że możesz zmodyfikować, jakiego typu executor zadań będzie używał po prostu zmieniając konfigurację Spring. W poniższym przykładzie biorę przykładową klasę (ClassWithMethodToFire) i owijam ją w obiekt Runnable, aby rozpalić ogień; możesz także zaimplementować Runnable w klasie własnej, a następnie w metodzie execute zadzwonisz pod numer classWithMethodToFire.run().

Oto bardzo prosty przykład.

public class SomethingThatShouldHappenInAThread { 
    private TaskExecutor taskExecutor; 
    private ClassWithMethodToFire classWithMethodToFire; 

    public SomethingThatShouldHappenInAThread(TaskExecutor taskExecutor, 
               ClassWithMethodToFire classWithMethodToFire) { 
      this.taskExecutor = taskExecutor; 
      this.classWithMethodToFire = classWithMethodToFire; 
    } 

    public void fire(final SomeParameterClass parameter) { 
      taskExecutor.execute(new Runnable() { 
       public void run() { 
        classWithMethodToFire.doSomething(parameter); 
       } 
      }); 
    } 
} 

A oto fasola Wiosna:

<bean name="somethingThatShouldHappenInAThread" class="package.name.SomethingThatShouldHappenInAThread"> 
    <constructor-arg type="org.springframework.core.task.TaskExecutor" ref="taskExecutor" /> 
    <constructor-arg type="package.name.ClassWithMethodToFire" ref="classWithMethodToFireBean"/> 
</bean> 

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
    <property name="corePoolSize" value="5" /> 
    <property name="maxPoolSize" value="10" /> 
    <property name="queueCapacity" value="25" /> 
</bean> 
+0

Myślę, że mój problem jest myślenie jest bardziej skomplikowane to jest. Widziałem http://docs.huihoo.com/javadoc/spring/2.0/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html#createQueue)) i założyłem, że ThreadPoolTaskExecutor ma wbudowany mechanizm kolejkowania. –

+0

Może się nie mylę, do czego służy funkcja queueCapacity? Wciąż czuję, że tu coś pomijam. –

+12

Jeśli pojemność kolejki jest większa niż 0, tworzy kolejkę, aby zadania uruchamiane przez określonego TaskExecutora mogły czekać, aż wątek będzie dostępny z puli. Pojemność wskazuje, ile spacji znajduje się w kolejce. Jeśli kolejka się zapełni, executor zablokuje (tzn. Metoda wykonania nie powróci, dopóki nie otworzy się spacja). Oto dokument w kolejce: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/LinkedBlockingQueue.html –