Spring threads in web application
I am writing a server for an MMO browser and I need to do multiple threads. They will work all the time with some sleep time. Is it a good idea to use spring tags 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 a task executor implemented as a 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>
In addition, threads run in a singleton, also defined as a bean.
What could be wrong with my approach?
source to share
You can use @Scheduled(fixedDelay = 5000)
to execute a batch method. Don't forget to set @EnableScheduling
for the class containing your main method.
There are two options for annotation @Scheduled
- fixedDelay
and fixedRate
.
fixedDelay
will continuously execute your method with a delay of X milliseconds after the last execution completes.
fixedRate
will continuously execute your fixed date method. Thus, every X milisecond this method will be executed regardless of the completion of the last execution.
You can also use @Async
it if you want to process many objects at the same time. Once again, you need to add @EnableAsync
to your class using the 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 pool size by expanding AsyncConfigurerSupport
and redefining getAsyncExecutor
. More information on this approach can be found in the links below.
I suggest you take a look at:
source to share
You can use @Async in case you want to program one thread (for example, you want to send 50 emails and you send them creating 50 different threads, each sending one message, and then wait for all threads to finish), or @Scheduled so that the method / thread runs at a fixed speed (or some time after the previous end of execution).
You can take a look at https://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-annotation-support for more 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!
}
}
}
}
source to share