当前位置:首页 > JavaScript

js 实现同步锁

2026-02-03 03:57:01JavaScript

同步锁的概念

在JavaScript中,由于单线程和事件循环机制,传统的多线程同步锁概念并不直接适用。但通过Promise、Async/Await或共享状态管理,可以模拟类似同步锁的行为,控制异步代码的执行顺序。

使用Promise实现同步锁

通过Promise链和闭包维护锁状态,确保异步操作按顺序执行:

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

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

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

// 使用示例
const lock = new Lock();
async function criticalSection() {
  await lock.acquire();
  try {
    // 临界区代码
  } finally {
    lock.release();
  }
}

使用Async/Await与标志位

通过标志位和循环等待实现简单锁:

js 实现同步锁

let locked = false;

async function withLock(fn) {
  while (locked) {
    await new Promise(resolve => setTimeout(resolve, 10));
  }
  locked = true;
  try {
    return await fn();
  } finally {
    locked = false;
  }
}

// 使用示例
await withLock(async () => {
  // 临界区代码
});

使用Atomics实现低级锁(SharedArrayBuffer环境)

在Web Worker共享内存场景下,可使用Atomics API:

const lockBuffer = new SharedArrayBuffer(4);
const lockView = new Int32Array(lockBuffer);

async function acquireLock() {
  while (Atomics.wait(lockView, 0, 1) !== 'ok') {
    // 等待锁释放
  }
  Atomics.store(lockView, 0, 1); // 获取锁
}

function releaseLock() {
  Atomics.store(lockView, 0, 0);
  Atomics.notify(lockView, 0, 1); // 通知等待线程
}

注意事项

  • 浏览器环境中优先使用Promise或Async/Await方案
  • Node.js可通过async-mutex等库直接实现
  • 避免死锁:确保锁最终被释放,使用try-finally块
  • 考虑锁粒度:过细影响性能,过粗降低并发性

第三方库推荐

  1. async-mutex:支持互斥锁和信号量

    js 实现同步锁

    npm install async-mutex
    const { Mutex } = require('async-mutex');
    const mutex = new Mutex();
    
    async function run() {
      const release = await mutex.acquire();
      try {
        // 临界区
      } finally {
        release();
      }
    }
  2. proper-lockfile:适用于文件操作场景

  3. redis-lock:分布式环境下的Redis锁实现

标签: js
分享给朋友:

相关文章

js如何实现继承

js如何实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例能够访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js实现瀑布流

js实现瀑布流

实现瀑布流布局 瀑布流布局是一种常见的网页布局方式,常用于图片展示、商品列表等场景。以下是使用 JavaScript 实现瀑布流布局的几种方法。 纯 JavaScript 实现 通过计算元素的位置和…

js实现预览

js实现预览

文件上传预览实现 使用JavaScript实现文件上传预览功能,可以通过FileReader对象读取文件内容并显示预览。以下代码支持图片、文本和PDF文件的预览: // HTML部分需要包含inpu…

js实现投球

js实现投球

实现投球动画的基本思路 使用JavaScript和CSS动画结合的方式模拟投球效果。核心是通过改变元素的位置、旋转和缩放属性,配合定时器或CSS过渡实现平滑动画。 创建基础HTML结构 <di…

js实现目录

js实现目录

实现目录的基本思路 在JavaScript中实现目录功能通常涉及以下几个核心步骤:解析文档中的标题元素(如h1-h6),动态生成目录结构,并添加交互逻辑(如点击跳转)。以下是具体实现方法: 解析标题…

js实现按钮点击

js实现按钮点击

实现按钮点击的JavaScript方法 HTML按钮元素 在HTML中创建按钮元素,为其添加id或class以便JavaScript选择: <button id="myButton">点…