当前位置:首页 > JavaScript

js实现锁

2026-04-05 11:20:17JavaScript

实现互斥锁(Mutex)

在JavaScript中实现锁机制可以通过Promise和异步控制实现。以下是一个基于Promise的互斥锁实现:

class Mutex {
  constructor() {
    this._locked = false;
    this._queue = [];
  }

  lock() {
    return new Promise((resolve) => {
      if (!this._locked) {
        this._locked = true;
        resolve();
      } else {
        this._queue.push(resolve);
      }
    });
  }

  unlock() {
    if (this._queue.length > 0) {
      const nextResolve = this._queue.shift();
      nextResolve();
    } else {
      this._locked = false;
    }
  }
}

使用示例:

const mutex = new Mutex();

async function criticalSection() {
  await mutex.lock();
  try {
    // 临界区代码
  } finally {
    mutex.unlock();
  }
}

读写锁实现

对于读写分离场景,可以实现读写锁:

class ReadWriteLock {
  constructor() {
    this._readers = 0;
    this._writers = 0;
    this._writeQueue = [];
    this._readQueue = [];
  }

  async readLock() {
    return new Promise((resolve) => {
      if (this._writers === 0 && this._writeQueue.length === 0) {
        this._readers++;
        resolve();
      } else {
        this._readQueue.push(resolve);
      }
    });
  }

  async writeLock() {
    return new Promise((resolve) => {
      if (this._readers === 0 && this._writers === 0) {
        this._writers++;
        resolve();
      } else {
        this._writeQueue.push(resolve);
      }
    });
  }

  readUnlock() {
    this._readers--;
    if (this._readers === 0 && this._writeQueue.length > 0) {
      const nextResolve = this._writeQueue.shift();
      this._writers++;
      nextResolve();
    }
  }

  writeUnlock() {
    this._writers--;
    if (this._readQueue.length > 0) {
      while (this._readQueue.length > 0) {
        const nextResolve = this._readQueue.shift();
        this._readers++;
        nextResolve();
      }
    } else if (this._writeQueue.length > 0) {
      const nextResolve = this._writeQueue.shift();
      this._writers++;
      nextResolve();
    }
  }
}

基于SharedArrayBuffer的原子锁

在支持SharedArrayBuffer的环境中,可以使用Atomics API实现真正的原子锁:

// 必须在跨上下文环境(如Web Worker)中才能使用
const lockBuffer = new SharedArrayBuffer(4);
const lock = new Int32Array(lockBuffer);

function acquireLock() {
  while (true) {
    // 尝试获取锁
    const oldValue = Atomics.compareExchange(lock, 0, 0, 1);
    if (oldValue === 0) {
      return; // 成功获取锁
    }
    // 等待锁释放
    Atomics.wait(lock, 0, 1);
  }
}

function releaseLock() {
  // 释放锁
  Atomics.store(lock, 0, 0);
  // 唤醒一个等待的线程
  Atomics.notify(lock, 0, 1);
}

使用async-mutex库

对于生产环境,推荐使用成熟的第三方库如async-mutex

js实现锁

import { Mutex } from 'async-mutex';

const mutex = new Mutex();

async function criticalSection() {
  const release = await mutex.acquire();
  try {
    // 临界区代码
  } finally {
    release();
  }
}

这些实现方法各有适用场景,互斥锁适合简单同步需求,读写锁适合读多写少场景,原子锁适合真正的多线程环境,而第三方库则提供了更完善的解决方案。

标签: js
分享给朋友:

相关文章

js实现分页

js实现分页

分页的基本实现思路 在JavaScript中实现分页功能通常需要结合前端和后端逻辑。前端负责渲染分页控件和处理用户交互,后端负责提供分页数据。 前端分页实现 纯前端分页适用于数据量较小的情况,可以直…

js轮播图实现原理

js轮播图实现原理

轮播图的基本原理 轮播图通过动态切换显示的内容(图片、文本等)实现视觉上的滑动效果。核心原理是利用CSS和JavaScript控制元素的显示与隐藏,或通过变换位置实现滑动动画。 实现方法一:…

js分组实现

js分组实现

分组实现方法 在JavaScript中,可以通过多种方式实现数组或对象的分组操作。以下是几种常见的方法: 使用Array.prototype.reduce() 通过reduce方法可以轻松实现数组分…

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…

js实现图

js实现图

JavaScript 实现图的常用方法 在 JavaScript 中,图(Graph)可以通过多种方式实现,常见的包括邻接表(Adjacency List)和邻接矩阵(Adjacency Matrix…

js实现吸色

js实现吸色

使用Canvas实现吸色功能 通过Canvas的getImageData方法获取像素颜色数据。创建一个Canvas元素,将目标图像绘制到Canvas上,通过鼠标事件获取坐标对应的颜色值。 const…