js实现锁
实现互斥锁(Mutex)
在JavaScript中实现锁机制可以通过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._readQueue = [];
this._writeQueue = [];
}
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();
}
}
}
使用Atomics实现锁
在SharedArrayBuffer环境下可以使用Atomics实现更底层的锁:
// 在Worker线程中
const sharedBuffer = new SharedArrayBuffer(4);
const lock = new Int32Array(sharedBuffer);
// 加锁
Atomics.wait(lock, 0, 0); // 等待锁可用
Atomics.store(lock, 0, 1); // 获取锁
// 解锁
Atomics.store(lock, 0, 0); // 释放锁
Atomics.notify(lock, 0, 1); // 通知等待的线程
使用Web Locks API
现代浏览器提供了Web Locks API:
navigator.locks.request('resource_name', async lock => {
// 临界区代码
});
注意事项
JavaScript是单线程语言,大多数锁机制用于协调异步操作或Web Worker间的同步。主线程中的同步代码不需要锁机制,因为JavaScript的事件循环保证了代码执行的原子性。
对于Web Worker间的同步,SharedArrayBuffer和Atomics提供了底层同步原语,但需要服务器设置适当的CORS头。
Web Locks API是最新的标准方法,但浏览器兼容性需要考虑。







