Reputation: 49
I am writing server for MMO browser game, and I need to make few threads. They will be running all the time with some sleep time. Is it good idea, to use spring threads like this?
@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");
}
}
with task executor implemented as bean?
<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>
Also, threads are started in singleton also defined as a bean.
What can be wrong in my approach?
Upvotes: 3
Views: 1681
Reputation: 2570
You can use @Scheduled(fixedDelay = 5000)
to execute a method periodic. Remember to set @EnableScheduling
for class containing your main method.
There are two options for the @Scheduled
annotation - fixedDelay
and fixedRate
.
fixedDelay
will continuously execute your method with a delay of X miliseconds after the last execution has finished.
fixedRate
will continuously execute your method with at a fixed date. So every X milisecond this method will be executed regardless if the last execution has finished.
You can also use @Async
if you want to process a bunch of objects all at once. Once again, you need to add @EnableAsync
to your class with your main method.
Example
//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++;
}
}
Bonus
You can get rid of your XML configuration for the pool size by extending AsyncConfigurerSupport
and override getAsyncExecutor
. More information about this approach can be found at the below links
I suggest that you take a look at:
https://spring.io/guides/gs/scheduling-tasks/
https://spring.io/guides/gs/async-method/
Upvotes: 2
Reputation: 1583
You can use @Async in case you want to invoke a single thread programmatically (e.g. you want to send 50 mail and you send them creating 50 different thread, each one to send a single message, then wait until all threads end), or @Scheduled to let a method / thread run at fixed rate (or after some time from previous execution end).
You can put an eye on https://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-annotation-support for further details.
@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!
}
}
}
}
Upvotes: 0