导读:本期聚焦于小伙伴创作的《如何利用数组实现简单的任务调度优先级列表并处理变量抢占逻辑》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何利用数组实现简单的任务调度优先级列表并处理变量抢占逻辑》有用,将其分享出去将是对创作者最好的鼓励。

在轻量级开发场景中,任务调度不需要依赖复杂的第三方框架,使用数组就能实现基础的优先级调度列表,同时处理变量抢占逻辑。这种方式实现成本低,适合资源受限的环境使用。

如何利用数组实现简单的任务调度优先级列表并处理变量抢占逻辑

任务结构定义

首先需要定义任务的基础结构,包含任务唯一标识、优先级、任务执行函数、需要占用的变量标识等核心信息。优先级数值越小代表优先级越高,变量标识用于标记任务执行时需要占用的共享资源。

// 定义任务结构
class Task {
    constructor(id, priority, executeFn, needVar) {
        this.id = id; // 任务唯一ID
        this.priority = priority; // 优先级,数值越小优先级越高
        this.executeFn = executeFn; // 任务执行函数
        this.needVar = needVar; // 任务需要占用的变量标识,如'var1'
        this.status = 'pending'; // 任务状态:pending/waiting/running/done
    }
}

优先级列表的数组维护

优先级列表本质是一个按优先级排序的任务数组,新任务加入时需要插入到正确的位置,保证数组始终按优先级升序排列。同时需要维护一个当前被占用的变量集合,用于判断抢占逻辑。

初始化调度器

调度器包含任务列表、已占用变量集合两个核心属性,同时提供添加任务、执行调度、处理抢占的方法。

// 初始化任务调度器
class TaskScheduler {
    constructor() {
        this.taskList = []; // 优先级排序的任务数组
        this.occupiedVars = new Set(); // 当前被占用的变量集合
    }
}

添加任务到优先级列表

添加任务时遍历现有任务数组,找到第一个优先级比新任务低的任务位置,插入新任务,保证数组始终有序。如果数组为空则直接添加。

// 添加任务到优先级列表
addTask(task) {
    let insertIndex = this.taskList.length;
    // 找到插入位置
    for (let i = 0; i < this.taskList.length; i++) {
        if (this.taskList[i].priority > task.priority) {
            insertIndex = i;
            break;
        }
    }
    // 插入任务
    this.taskList.splice(insertIndex, 0, task);
    console.log(`任务${task.id}已添加到优先级列表,当前列表长度:${this.taskList.length}`);
}

变量抢占逻辑处理

变量抢占指高优先级任务需要占用低优先级任务正在使用的变量时,低优先级任务需要释放变量,进入等待状态,高优先级任务获取变量后执行。处理流程分为三步:判断变量是否被占用、处理被占用变量的低优先级任务、执行高优先级任务。

检查变量占用情况

当新任务加入或准备执行时,先检查任务需要的变量是否已经被占用,如果被占用则找到占用该变量的低优先级任务。

// 检查变量是否被占用,返回占用该变量的任务,没有则返回null
checkVarOccupied(varId) {
    for (let task of this.taskList) {
        if (task.needVar === varId && (task.status === 'running' || task.status === 'waiting')) {
            return task;
        }
    }
    return null;
}

处理抢占逻辑

如果高优先级任务需要的变量被低优先级任务占用,低优先级任务状态改为waiting,释放变量,高优先级任务状态改为running,占用变量。如果低优先级任务已经在等待其他变量,则不需要重复处理。

// 处理变量抢占逻辑
handlePreemption(newTask) {
    const occupiedTask = this.checkVarOccupied(newTask.needVar);
    // 如果没有任务占用该变量,直接标记新任务为可运行
    if (!occupiedTask) {
        newTask.status = 'running';
        this.occupiedVars.add(newTask.needVar);
        return;
    }
    // 如果占用任务的优先级比新任务低,执行抢占
    if (occupiedTask.priority > newTask.priority) {
        // 低优先级任务进入等待状态,释放变量
        occupiedTask.status = 'waiting';
        this.occupiedVars.delete(occupiedTask.needVar);
        // 高优先级任务获取变量,进入运行状态
        newTask.status = 'running';
        this.occupiedVars.add(newTask.needVar);
        console.log(`任务${newTask.id}抢占任务${occupiedTask.id}的变量${newTask.needVar}`);
    } else {
        // 新任务优先级更低,进入等待状态
        newTask.status = 'waiting';
    }
}

调度执行方法

调度时遍历优先级列表,先处理等待状态中变量已释放的任务,再执行第一个处于pending状态的高优先级任务,触发抢占逻辑。

// 执行调度
runSchedule() {
    // 先检查等待状态的任务是否可以恢复
    for (let task of this.taskList) {
        if (task.status === 'waiting' && !this.occupiedVars.has(task.needVar)) {
            task.status = 'running';
            this.occupiedVars.add(task.needVar);
            console.log(`任务${task.id}恢复运行,占用变量${task.needVar}`);
            task.executeFn();
            task.status = 'done';
            this.occupiedVars.delete(task.needVar);
        }
    }
    // 执行第一个pending状态的最高优先级任务
    for (let task of this.taskList) {
        if (task.status === 'pending') {
            this.handlePreemption(task);
            if (task.status === 'running') {
                console.log(`开始执行任务${task.id},优先级${task.priority}`);
                task.executeFn();
                task.status = 'done';
                this.occupiedVars.delete(task.needVar);
            }
            break;
        }
    }
}

完整示例测试

下面创建三个不同优先级的任务,测试优先级排序和变量抢占逻辑是否生效。

// 定义任务执行函数
function task1Execute() {
    console.log('任务1执行完成,释放变量var1');
}
function task2Execute() {
    console.log('任务2执行完成,释放变量var1');
}
function task3Execute() {
    console.log('任务3执行完成,不需要占用变量');
}

// 初始化调度器
const scheduler = new TaskScheduler();
// 创建任务:任务1优先级2,需要var1;任务2优先级1,需要var1;任务3优先级3,不需要变量
const task1 = new Task(1, 2, task1Execute, 'var1');
const task2 = new Task(2, 1, task2Execute, 'var1');
const task3 = new Task(3, 3, task3Execute, null);

// 添加任务到调度器
scheduler.addTask(task1);
scheduler.addTask(task2);
scheduler.addTask(task3);

// 执行调度
console.log('第一次调度:');
scheduler.runSchedule();
console.log('第二次调度:');
scheduler.runSchedule();

上述示例中,任务2优先级最高,会抢占任务1的变量var1先执行,任务1进入等待状态,等任务2执行完释放变量后,任务1再恢复执行,最后执行任务3,符合预期的调度和抢占逻辑。

注意事项

  • 数组插入操作的时间复杂度为O(n),如果任务数量过多,建议改用二叉堆等数据结构优化性能
  • 变量标识需要保证唯一性,避免不同变量被误判为同一资源
  • 如果任务执行时间较长,需要增加任务中断逻辑,避免高优先级任务长时间等待
  • 任务执行完成后需要及时清理状态,避免占用变量不释放导致死锁

任务调度优先级列表数组变量抢占修改时间:2026-07-08 16:03:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。