Backend Development 17 min read

Understanding Task Scheduling: Quartz, Distributed Locks, ElasticJob‑Lite, XXL‑JOB and a Custom Solution

This article explains the core concepts, architectures and trade‑offs of several Java task‑scheduling solutions—including Quartz, Redis/Zookeeper distributed locks, ElasticJob‑Lite, XXL‑JOB and a self‑built scheduler—while providing code examples and practical guidance for building reliable, scalable job execution systems.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Understanding Task Scheduling: Quartz, Distributed Locks, ElasticJob‑Lite, XXL‑JOB and a Custom Solution

1 Quartz

Quartz is an open‑source Java job‑scheduling framework. Its core components are Job (the task to be executed), Trigger (defines when the job runs) and Scheduler (creates Scheduler instances and drives execution).

The default in‑memory store is RAMJobStore , which keeps jobs and triggers in RAM. The main execution thread is QuartzSchedulerThread , which repeatedly:

Fetches the list of triggers that need to fire from the JobStore and updates their state.

Fires each trigger, updating the next‑fire time and persisting the change.

Creates a concrete task object and submits it to a worker thread pool.

In clustered mode Quartz uses JobStoreSupport backed by a relational database (MySQL, Oracle). It obtains row‑level locks on the QRTZ_LOCKS table (e.g., TRIGGER_ACCESS , STATE_ACCESS ) to guarantee that only one node executes a given trigger at a time.

2 Distributed‑Lock Mode

When a simple Spring @Scheduled task runs on multiple instances, concurrent execution can cause data inconsistency. The solution is to acquire a distributed lock (Redis or Zookeeper) before performing the business logic.

@Scheduled(cron = "0 */2 * * * ?")
public void doTask() {
    log.info("Task start");
    String lockName = "closeExpireUnpayOrdersLock";
    RedisLock redisLock = redisClient.getLock(lockName);
    boolean locked = redisLock.tryLock(3, 300, TimeUnit.SECONDS);
    if (!locked) {
        log.info("Failed to acquire lock:{}", lockName);
        return;
    }
    try {
        orderService.closeExpireUnpayOrders();
    } finally {
        redisLock.unlock();
    }
    log.info("Task end");
}

Redis provides high‑performance read/write and lightweight locking; Zookeeper can be used as an alternative.

Two drawbacks of the Quartz/Spring Schedule + Redis lock combination are:

In a distributed environment the scheduled job may run empty or cannot be sharded.

Manual triggering requires additional code.

3 ElasticJob‑Lite

ElasticJob‑Lite is a lightweight, non‑centralized solution that ships as a JAR. Users implement the SimpleJob interface and write their own business logic.

public class MyElasticJob implements SimpleJob {
    @Override
    public void execute(ShardingContext context) {
        switch (context.getShardingItem()) {
            case 0:
                // do something for shard 0
                break;
            case 1:
                // do something for shard 1
                break;
            case 2:
                // do something for shard 2
                break;
            // ... other shards
        }
    }
}

ElasticJob internally still relies on Quartz for scheduling, but uses Zookeeper for coordination and load‑balancing of jobs across multiple machines.

4 Centralized Approaches

4.1 MQ Mode

The scheduler runs in Quartz cluster mode and, when a trigger fires, sends a message to RabbitMQ. Consumer applications receive the message and execute the business logic, achieving decoupling at the cost of a strong dependency on the message queue.

4.2 XXL‑JOB

XXL‑JOB is a distributed scheduling platform that aims for simplicity and extensibility. Early versions depended on Quartz; since v2.1.0 the Quartz dependency was removed and custom tables are used instead.

The core scheduling class is JobTriggerPoolHelper , which starts two threads: scheduleThread (loads tasks from the database using row‑level locks) and ringThread (executes tasks whose next fire time is within a short window).

Connection conn = XxlJobAdminConfig.getAdminConfig()
    .getDataSource().getConnection();
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement(
    "select * from xxl_job_lock where lock_name = 'schedule_lock' for update");
ps.execute();
// pseudo‑code: trigger tasks
for (XxlJobInfo jobInfo : scheduleList) {
    // ...
}
conn.commit();

XXL‑JOB supports three routing strategies: random, broadcast, and sharding, allowing flexible deployment of jobs across a cluster.

5 Self‑Built Scheduler on Top of Existing Tools

In 2018 the author built a custom scheduler that integrates a proprietary RPC framework, re‑uses Quartz cluster mode for execution, and adopts RocketMQ's remoting module for network communication. Processors such as CallBackProcessor , HeartBeatProcessor and TriggerTaskProcessor are registered via the registerProcessor API.

public void registerProcessor(int requestCode,
                              NettyRequestProcessor processor,
                              ExecutorService executor);

The custom system was deployed in production for about four months, handling 40‑50 million executions with stable performance, though the row‑level lock model of Quartz limited scalability.

6 Technology Selection

A comparison table (not reproduced here) shows that Quartz and ElasticJob are framework‑level solutions, while centralized products such as XXL‑JOB or commercial SchedulerX provide richer features like workflow, map‑reduce style sharding, and high‑availability.

Regardless of the chosen stack, two best practices are emphasized:

Make jobs idempotent to tolerate retries or lock failures.

When a job stops, check scheduler logs, use jstack for JVM diagnostics, and ensure network time‑outs are configured.

7 Closing Remarks

The author notes that both ElasticJob and XXL‑JOB were open‑sourced in 2015, and encourages readers to follow the public account for more technical articles and PDFs.

BackendJavatask schedulingDistributed Lockxxl-jobQuartzElasticJob
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.