toddeTV
toddeTV

Reputation: 1517

java scheduler spring vs quartz

Currently I am building a spring standalone program in order to learn new methods and architectures.
The last few days I tried to learn scheduler. I never used them before so I read some articles handling the different possible methods. Two of them are especially interesting: The spring nativ @Scheduler and Quartz.

From what I read, Spring is a little bit smaller then Quartz and much more basic. And quartz is not easy to use with spring (because of the autowired and components).

My problem now is, that there is one thing I do not understand:
From my understanding, both methods are creating parallel Threads in order to asynchronously run the jobs. But what if I now have a spring @Service in my main Application, that is holding a HashMap with some information. The data is updated and changed with user interaction. Parallel there are the scheduler. And a scheduler now whants to use this HashMap from the main application as well. Is this even possible?
Or do I understand something wrong? Because there is also the @Async annotation and I did not understand the difference. Because a scheduler itself is already parallel to the main corpus, isn't it?

(summing up, two questions:

)

Upvotes: 2

Views: 2926

Answers (1)

Eric G
Eric G

Reputation: 134

I have to make a few assumptions about which version of Spring you're using but as you're in the process of learning, I would assume that you're using spring-boot or a fairly new version, so please excuse if the annotations don't match your version of Spring. This said, to answer your two questions the best I can:

can a job that is executed every five seconds, implemented with a scheduler, use a HashMap out of a service inside the main program? (in spring @Scheduler and/or in Quartz?)

Yes, absolutely! The easiest way is to make sure that the hashmap in question is declared as static. To access the hashmap from the scheduled job, simply either autowire your service class or create a static get function for the hashmap.

Here is an example of a recent Vaadin project where I needed a scheduled message sent to a set of subscribers.

SchedulerConfig.class

@Configuration
@EnableAsync
@EnableScheduling
public class SchedulerConfig {

    @Scheduled(fixedDelay=5000)
    public void refreshVaadinUIs() {
        Broadcaster.broadcast( 
                new BroadcastMessage(
                    BroadcastMessageType.AUTO_REFRESH_LIST 
                ) 
        );
    }

}

Broadcaster.class

public class Broadcaster implements Serializable {

    private static final long serialVersionUID = 3540459607283346649L;

    private static ExecutorService executorService = Executors.newSingleThreadExecutor();

    private static LinkedList<BroadcastListener> listeners = new LinkedList<BroadcastListener>();

    public interface BroadcastListener {
        void receiveBroadcast(BroadcastMessage message);
    }   

    public static synchronized void register(BroadcastListener listener) {
        listeners.add(listener);
    }

    public static synchronized void unregister(BroadcastListener listener) {
        listeners.remove(listener);
    }

    public static synchronized void broadcast(final BroadcastMessage message) {
        for (final BroadcastListener listener: listeners)
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    listener.receiveBroadcast(message);
                }
            });
    }
}

Why is there a @Async annotation. Isn't a scheduler already parallel to the main process?

Yes, the scheduler is running in its own thread but what occurs to the scheduler on long running tasks (ie: doing a SOAP call to a remote server that takes a very long time to complete)?

The @Async annotation isn't required for scheduling but if you have a long running function being invoked by the scheduler, it becomes quite important.

This annotation is used to take a specific task and request to Spring's TaskExecutor to execute it on its own thread instead of the current thread. The @Async annotation causes the function to immediately return but execution will be later made by the TaskExecutor.

This said, without the @EnableAsync or @Async annotation, the functions you call will hold up the TaskScheduler as they will be executed on the same thread. On a long running operation, this would cause the scheduler to be held up and unable to execute any other scheduled functions until it returns.

I would suggest a read of Spring's Documentation about Task Execution and Scheduling It provides a great explanation of the TaskScheduler and TaskExecutor in Spring

Upvotes: 4

Related Questions