2017-03-31 103 views
3

我正在为MMO浏览器游戏编写服务器,并且我需要制作几个线程。 他们会在一段时间的睡眠中运行。 使用这样的弹簧线是好主意吗?在web应用中的弹簧线程

@Component 
@Scope("prototype") 
public class PrintTask2 implements Runnable{ 

String name; 

public void setName(String name){ 
    this.name = name; 
} 

@Override 
public void run() { 

    System.out.println(name + " is running"); 

    try { 
     Thread.sleep(5000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    System.out.println(name + " is running"); 

} 

}

与任务执行器实现为豆?

<bean id="taskExecutor" 
     class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
    <property name="corePoolSize" value="5" /> 
    <property name="maxPoolSize" value="10" /> 
    <property name="WaitForTasksToCompleteOnShutdown" value="true" /> 
</bean> 

此外,线程也是以singleton启动的,也被定义为一个bean。

我的方法有什么问题?

+0

您是否解决了您的问题?只是问你是否需要更多的帮助。 – kkflf

回答

2

您可以使用@Scheduled(fixedDelay = 5000)定期执行方法。请记得为包含主要方法的类设置@EnableScheduling

@Scheduled注释有两个选项 - fixedDelayfixedRate

fixedDelay将在上次执行完成后延迟X毫秒的时间继续执行您的方法。

fixedRate将在固定的日期持续执行您的方法。因此,无论最后一次执行完成,每X毫秒该方法都将被执行。

如果您想一次处理大量对象,也可以使用@Async。再一次,您需要使用主要方法将@EnableAsync添加到您的课程中。

//Remember to set @EnableScheduling 
//in the class containing your main method 
@SpringBootApplication 
@EnableScheduling 
@EnableAsync 
public class Application { 

    public static void main(String[] args) throws Exception { 
     SpringApplication.run(Application.class); 
    } 
} 

@Component 
public class ScheduledTasks { 

List<YourObject> myObjects; 

    //This method will run every 5 second. 
    @Scheduled(fixedDelay = 5000) 
    public void yourMethodName() { 
     //This will process all of your objects all at once using treads 
     for(YourObject yo : myObjects){ 
      yo.process(); 
     } 
    } 
} 

public class YourObject { 

    Integer someTest = 0; 

    @Async 
    public void process() { 
     someTest++; 
    } 
} 

奖金 您可以通过扩展AsyncConfigurerSupport并覆盖getAsyncExecutor摆脱对池大小的XML配置。有关此方法的更多信息可以在下面的链接中找到

我建议你看一看:

https://spring.io/guides/gs/scheduling-tasks/

https://spring.io/guides/gs/async-method/

+0

那么我真的不创建线程?听起来不错。当我没有主要方法(我没有使用SpringBoot)时,我应该在单线程中添加@EnableAsync注释,这是启动这个线程? – Parys

+0

好的,我找到了。如果有人会寻找类似的东西:可以通过在XML中放入 Parys

0

您可以在使用的情况下,你@Async要调用一个单线程以编程方式(例如,您想发送50封邮件,并发送它们创建50个不同的线程,每个线程发送一条消息,然后等待所有线程结束),或@Scheduled让方法/线程以固定速率运行(或之前执行结束后的一段时间)。

您可以关注https://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-annotation-support了解更多详情。

@Service 
public class MyAsyncStuff { 
    @Async 
    public Future<String> callMe(String param) { 
     // do your work here...   
     return new AsyncResult<String>("Sent: "+param);   
    } 
} 

@Service 
public class MyWorker { 
    @Inject 
    MyAsyncStuff stuff; 

    public void invoker() { 
     List<Future<String>> futures = new Arraylist<>(); 
     for (int i=0; i<10; i++) { 
      futures.add(stuff.callMe("Invoked "+i)); 
     } 
     for (Future<String> fut : futures) { 
      try { 
       System.out.println(futures.get(); 
      } catch (Exception e) { 
      // Spock? Do something! 
      } 
     } 
    } 
} 
+0

好吧,如果我想让单线程完成所有的工作而不是启动不同的工作,我应该使用@Scheduled?那么在单身人士中开始他们呢? – Parys

+0

这取决于你想完成什么。你是否有一个你希望一次处理的对象的集合,那么你需要使用@Async。如果您想要定期执行特定任务,那么您想使用'@ scheduled'。您还可以组合这两个注释,以定期执行一次处理一组对象的任务。 – kkflf

+0

(at)计划用于重复执行任务,例如如果你想在某个时间间隔检查一些东西。当你想要时,你不能停下来或开始。如果你想启动一个线程让它在后台创建一些东西,为了不阻止执行(例如准备一个zip文件,然后在完成时通过邮件发送它),一个(at)异步就是你需要的。 PrintTask可能属于第二种情况。 – Sampisa

相关问题