js 实现同步锁
同步锁的实现方法
在JavaScript中实现同步锁可以通过多种方式,以下是几种常见的方法:

使用Promise和async/await
通过Promise和async/await可以模拟同步锁的行为。创建一个锁变量,并在需要同步的代码块中使用await等待锁释放。

let lock = Promise.resolve();
async function withLock(fn) {
const oldLock = lock;
let releaseLock;
lock = new Promise(resolve => {
releaseLock = resolve;
});
await oldLock;
try {
return await fn();
} finally {
releaseLock();
}
}
// 使用示例
async function criticalSection() {
await withLock(async () => {
console.log('进入临界区');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('离开临界区');
});
}
使用Mutex库
可以使用第三方库如async-mutex来实现更复杂的锁机制。安装后直接使用其提供的Mutex类。
npm install async-mutex
const { Mutex } = require('async-mutex');
const mutex = new Mutex();
async function criticalSection() {
const release = await mutex.acquire();
try {
console.log('进入临界区');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('离开临界区');
} finally {
release();
}
}
使用Atomics和SharedArrayBuffer
对于多线程环境(如Web Worker),可以使用Atomics和SharedArrayBuffer实现低级锁。
const sharedBuffer = new SharedArrayBuffer(4);
const sharedArray = new Int32Array(sharedBuffer);
const LOCKED = 1;
const UNLOCKED = 0;
function acquireLock() {
while (true) {
if (Atomics.compareExchange(sharedArray, 0, UNLOCKED, LOCKED) === UNLOCKED) {
return;
}
Atomics.wait(sharedArray, 0, LOCKED);
}
}
function releaseLock() {
if (Atomics.compareExchange(sharedArray, 0, LOCKED, UNLOCKED) !== LOCKED) {
throw new Error('Lock was not acquired');
}
Atomics.notify(sharedArray, 0, 1);
}
// 使用示例
acquireLock();
console.log('进入临界区');
setTimeout(() => {
console.log('离开临界区');
releaseLock();
}, 1000);
注意事项
- 在单线程环境中,JavaScript本身是事件驱动和非阻塞的,通常不需要锁机制。锁主要用于协调异步操作或Web Worker中的多线程场景。
- 使用锁可能导致性能问题或死锁,需谨慎设计。
SharedArrayBuffer在某些浏览器中可能受到限制,需检查兼容性。






