在Spring中实现线程功能的最佳方法

时间:2013-07-02 13:26:50

标签: java multithreading spring spring-mvc quartz-scheduler

我正在使用Spring 3.2进行Java聊天项目。

通常在Java中我可以创建这样的线程:

public class Listener extends Thread{
    public void run(){
         while(true){

         }
    }
}

并按start()启动帖子。

但在Spring 3.x中是否有任何特殊的类或任何特殊的方法来实现线程功能?


我的要求:

我有2个电信域名服务器。在我的应用程序中,我需要初始化服务器以创建协议。

初始化服务器后,我需要启动两个线程来监听来自电信域服务器的响应。

我所做的工作如下:

public class Listener extends Thread{
    public void run(){

       while(true){
           if(ServerOne.protocol != null){
                Message events = ServerOne.protocol.receive();
                   //Others steps to display the message in the view
           }
       }

    }
}


是否可以使用quartz

执行java线程功能

如果可能哪一个更好?如果没有意思,是什么原因?

希望我们的堆叠成员能够提供更好的解决方案。

4 个答案:

答案 0 :(得分:6)

Spring的TaskExecutor是在托管环境中运行这些线程的好方法。您可以参考http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html获取一些示例。

答案 1 :(得分:1)

Java有你需要的东西。我建议不要手动使用Thread。你应该总是使用管理线程的东西。请看一下:https://stackoverflow.com/a/1800583/2542027

答案 2 :(得分:1)

你可以使用Spring的ThreadPoolTaskExecutor
您可以在配置文件

中定义执行程序
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" destroy- method="shutdown">
  <property name="corePoolSize" value="2" />
  <property name="maxPoolSize" value="2" />
  <property name="queueCapacity" value="10" />
</bean>

<task:annotation-driven executor="taskExecutor" />

Listener中,您可以使用一种方法完成其中的所有工作,并使用@Async注释注释此方法。当然,Listener也应该是Spring管理的。

public class Listener{

    @Async
    public void doSomething(){

       while(true){
           if(ServerOne.protocol != null){
                Message events = ServerOne.protocol.receive();
                   //Others steps to display the message in the view
           }
       }

    }
}

现在每次调用doSomething时,如果执行程序运行的线程数少于corePoolSize,则会创建一个新线程。创建corePoolSize个线程后,每次对doSomething的后续调用只有在corePoolSize但小于maxPoolSize运行(非空闲)时才会创建新线程线程和线程队列已满。有关池大小的更多信息,请参阅java docs

注意:使用@Async时,如果您的应用程序中没有CGLIB库,则可能会遇到以下异常。

Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.

要在不必添加CGLIB依赖项的情况下解决此问题,您可以创建一个在其中包含doSomething()的接口IListener,然后Listener实现IListener

答案 3 :(得分:1)

从Spring 3开始,您可以使用@Schedule注释:

@Service
public class MyTest {
  ...
  @Scheduled(fixedDelay = 10)
  public getCounter() {...}
}

在上下文文件中使用<context:component-scan base-package="ch/test/mytest"><task:annotation-driven/>

请参阅本教程:http://spring.io/blog/2010/01/05/task-scheduling-simplifications-in-spring-3-0/