Estoy escribiendo un servidor para un juego de navegador MMO y necesito hacer algunos subprocesos. Estarán funcionando todo el tiempo con algo de tiempo para dormir. ¿Es buena idea usar hilos de resorte como este?
@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"); }}
con el ejecutor de tareas implementado como 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>Además, los subprocesos se inician en singleton, también definido como un bean.
¿Qué puede estar mal en mi enfoque?
Puede usar @Scheduled(fixedDelay = 5000) para ejecutar un método periódico. Recuerde configurar @EnableScheduling para la clase que contiene su método principal.
Hay dos opciones para la anotación @Scheduled : fixedDelay y fixedRate .
fixedDelay ejecutará continuamente su método con un retraso de X milisegundos después de que finalice la última ejecución.
fixedRate ejecutará continuamente su método en una fecha fija. Entonces, cada X milisegundo, este método se ejecutará independientemente de si la última ejecución ha terminado.
También puede usar @Async si desea procesar varios objetos a la vez. Una vez más, debe agregar @EnableAsync a su clase con su método principal.
Ejemplo
//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++; } } Bonificación Puede deshacerse de su configuración XML para el tamaño del grupo al extender AsyncConfigurerSupport y anular getAsyncExecutor . Puede encontrar más información sobre este enfoque en los siguientes enlaces
Te sugiero que le eches un vistazo a:
Puede usar @Async en caso de que desee invocar un único subproceso mediante programación (por ejemplo, desea enviar 50 correos y los envía creando 50 subprocesos diferentes, cada uno para enviar un solo mensaje, luego espere hasta que finalicen todos los subprocesos), o @ Programado para permitir que un método/subproceso se ejecute a una velocidad fija (o después de un tiempo desde el final de la ejecución anterior).
Puede consultar https://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-annotation-support para obtener más detalles.
@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! } } } }