面试题答案
一键面试设计思路
- 锁机制:使用互斥锁(Mutex)来确保同一时间只有一个线程能够对数组进行写操作。读操作可以允许多个线程同时进行,但在有写操作时,读操作需要等待写操作完成。
- 版本控制:为数组添加版本号,每次写操作增加版本号。读操作时记录当前版本号,如果在读操作过程中版本号发生变化,说明数据被修改,需要重新读取。
- 错误捕获:在读写操作的关键位置使用
try - catch
块来捕获可能出现的错误,如读写冲突或数据不一致错误。
关键代码实现
- 使用Web Workers模拟多线程环境:
- 主线程代码(index.js):
// 创建一个新的Web Worker
const worker = new Worker('worker.js');
// 向Worker发送数组数据
const sharedArray = [1, 2, 3, 4];
worker.postMessage({ action: 'init', data: sharedArray });
// 监听来自Worker的消息
worker.onmessage = function (e) {
if (e.data.error) {
console.error('Error in worker:', e.data.error);
} else {
console.log('Updated array from worker:', e.data.result);
}
};
// 模拟主线程对数组的写操作
setTimeout(() => {
worker.postMessage({ action: 'write', data: [5, 6] });
}, 2000);
- Web Worker代码(worker.js):
let sharedArray;
let version = 0;
let lock = false;
self.onmessage = function (e) {
try {
if (e.data.action === 'init') {
sharedArray = e.data.data;
} else if (e.data.action ==='read') {
if (lock) {
throw new Error('Read conflict: Write operation in progress');
}
const currentVersion = version;
self.postMessage({ result: sharedArray, version: currentVersion });
} else if (e.data.action === 'write') {
if (lock) {
throw new Error('Write conflict: Another write operation in progress');
}
lock = true;
sharedArray = e.data.data;
version++;
lock = false;
self.postMessage({ result: sharedArray, version: version });
}
} catch (error) {
self.postMessage({ error: error.message });
}
};
- 使用JavaScript原生多线程(Node.js的worker_threads模块):
- 主线程代码(main.js):
const { Worker } = require('worker_threads');
// 创建一个新的Worker
const worker = new Worker('worker.js');
// 向Worker发送数组数据
const sharedArray = [1, 2, 3, 4];
worker.postMessage({ action: 'init', data: sharedArray });
// 监听来自Worker的消息
worker.on('message', function (e) {
if (e.error) {
console.error('Error in worker:', e.error);
} else {
console.log('Updated array from worker:', e.result);
}
});
// 模拟主线程对数组的写操作
setTimeout(() => {
worker.postMessage({ action: 'write', data: [5, 6] });
}, 2000);
- Worker代码(worker.js):
const { parentPort } = require('worker_threads');
let sharedArray;
let version = 0;
let lock = false;
parentPort.on('message', function (e) {
try {
if (e.data.action === 'init') {
sharedArray = e.data.data;
} else if (e.data.action ==='read') {
if (lock) {
throw new Error('Read conflict: Write operation in progress');
}
const currentVersion = version;
parentPort.postMessage({ result: sharedArray, version: currentVersion });
} else if (e.data.action === 'write') {
if (lock) {
throw new Error('Write conflict: Another write operation in progress');
}
lock = true;
sharedArray = e.data.data;
version++;
lock = false;
parentPort.postMessage({ result: sharedArray, version: version });
}
} catch (error) {
parentPort.postMessage({ error: error.message });
}
});
以上代码通过锁机制和版本控制,结合错误捕获,在多线程环境下保证了数组数据的完整性和程序的稳定性。不同环境(浏览器Web Workers和Node.js worker_threads)下的实现思路类似,但具体API有所不同。