javaScript中worker實(shí)現(xiàn)線程池的示例代碼
目錄結(jié)構(gòu):

Lock
class Lock {
static locks = {};
static getInstance(key = ""){
let instance = this.locks[key];
if(null == instance){
instance = new Lock();
this.locks[key] = instance;
}
return instance;
}
constructor(){
const sab = new SharedArrayBuffer(4);
this._arr = new Int32Array(sab);
Atomics.store(this._arr, 0, 0);
}
acquireLock() {
let acquired = false;
while (!acquired) {
const expected = 0;
const actual = Atomics.compareExchange(this._arr, 0, expected, 1);
acquired = (actual === expected);
if(acquired){
// console.log('Lock acquired in worker thread');
return;
}
//console.log('Lock acquired in worker thread, wait');
Atomics.wait(this._arr, 0);
//console.log('Lock acquired in worker thread',"被喚醒");
}
}
releaseLock() {
// console.log('Lock released in worker thread');
Atomics.store(this._arr, 0, 0);
Atomics.notify(this._arr, 0);
}
}
module.exports = Lock;
BlockingQueue
let Lock = require('./Lock.js');
class BlockingQueue{
constructor(key = ""){
this._data = [];
this._lock = Lock.getInstance(key);
}
getSize(){
try{
this._lock.acquireLock();
return this._data.length;
}catch(e){
console.error(e);
}finally{
this._lock.releaseLock();
}
}
offer(message){
try{
this._lock.acquireLock();
this._data.push(message);
}catch(e){
console.error(e);
}finally{
this._lock.releaseLock();
}
}
pop(){
try{
this._lock.acquireLock();
return this._data.pop();
}catch(e){
console.error(e);
}finally{
this._lock.releaseLock();
}
}
popList(count = 1){
try{
this._lock.acquireLock();
let arr = [];
count = count > this._data.length ? this._data.length : count;
for(let index = 0; index < count; index ++){
arr.push(this._data.pop());
}
return arr;
}catch(e){
console.error(e);
}finally{
this._lock.releaseLock();
}
}
remove(arr){
try{
this._lock.acquireLock();
this._data = this._data.filter(item => !arr.includes(item));
}catch(e){
console.error(e);
}finally{
this._lock.releaseLock();
}
}
remove(item){
try{
this._lock.acquireLock();
this._data = this._data.filter(em => !em == item);
}catch(e){
console.error(e);
}finally{
this._lock.releaseLock();
}
}
getArr(){
try{
this._lock.acquireLock();
return this._data;
}catch(e){
console.error(e);
}finally{
this._lock.releaseLock();
}
}
}
module.exports = BlockingQueue;
Message
class Message{
constructor(data){
this._data = data;
}
getData(){
return this._data;
}
}
module.exports = Message;
線程實(shí)現(xiàn)
worker.js
const {
parentPort,
threadId
} = require('worker_threads');
parentPort.on('message', (msg) => {
let data = msg.data;
let fun = eval(msg.fun);
fun(data);
console.log("threadId=",threadId, " data=", msg)
//parentPort.postMessage(msg);
});
Thread
const {
Worker
} = require('worker_threads');
var path = require('path')
let workerJsPath = path.resolve(__dirname +'/worker.js')
class Thread {
constructor(runnable, name = "") {
this._name = name;
this._target = runnable;
this._interrupted = false;
}
run() {
this._target.run()
}
start() {
this._initForkThread();
}
stop(){
this._worker.terminate();
}
_initForkThread(){
this._worker = new Worker(workerJsPath);
// this._worker.on('message', (msg) => {
// this._target.data = msg;
// this._target.status = "done";
// console.log("收到回復(fù)", msg)
// });
this._worker.on('exit', (msg) => {
this._interrupted = true;
console.log("線程中斷")
});
}
isInterrupted(){
return this._interrupted;
}
getName(){
return this._name;
}
postMessage(message){
this._worker.postMessage({
fun: `${this._target}`,
data: message.data
});
}
}
module.exports = Thread;
TaskThread
class TaskThread{
constructor(thread, queue){
this._thread = thread;
this._queue = queue;
}
start(){
this._thread.start();
try{
let start = performance.now();
let interval = setInterval(() => {
if(!this.isInterrupted()){
let message = this._queue.pop();
if(null == message){
return;
}
this._thread.postMessage(message);
}else{
clearInterval(interval);
}
}, 500);
}catch(e){
console.error("錯(cuò)誤信息",e);
}
}
isInterrupted(){
return this._thread.isInterrupted();
}
}
module.exports = TaskThread;
ThreadPool
let Thread = require("./Thread.js")
let BlockingQueue = require("./BlockingQueue.js")
let TaskThread = require("./TaskThread.js")
class ThreadPool{
constructor(threadCount = 4){
this._count = threadCount;
this._queue = new BlockingQueue("queue");
this._threads = new BlockingQueue("thread")
setInterval(() => {
if(0 == this._queue.getSize()){
return;
}
//移除無(wú)效線程
let removeThreads = this._threads.getArr().map(thread => thread.isInterrupted());
this._threads.remove(removeThreads);
// //檢驗(yàn)線程數(shù)
let activeThreadCount = this._threads.getSize();
if(activeThreadCount < this._count && this._queue.getSize() > 0){
this.createThread(this._count - activeThreadCount);
}
}, 10);
}
createThread(count){
for(let index = 0; index < count; index ++ ){
let thread = new Thread((m) => {
console.log(m)
}, "fork_task_" + index);
let taskThread = new TaskThread(thread, this._queue);
this._threads.offer(taskThread);
taskThread.start();
}
}
addTask(message){
this._queue.offer(message);
}
}
module.exports = ThreadPool;
測(cè)試用例:
test.js
let ThreadPool = require("./ThreadPool.js")
let threadPool = new ThreadPool();
threadPool.addTask({
data: "99999"
})
threadPool.addTask({
data: "88888"
})
threadPool.addTask({
data: "77777"
})
運(yùn)行test.js
node test.js

到此這篇關(guān)于javaScript中worker實(shí)現(xiàn)線程池的文章就介紹到這了,更多相關(guān)javaScript worker線程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript之textarea打字機(jī)效果提示代碼推薦
非常不錯(cuò)的提示輸入內(nèi)容,動(dòng)態(tài)的提示,給人親切感2008-09-09
JS實(shí)現(xiàn)物體帶緩沖的間歇運(yùn)動(dòng)效果示例
這篇文章主要介紹了JS實(shí)現(xiàn)物體帶緩沖的間歇運(yùn)動(dòng)效果,可實(shí)現(xiàn)物體定時(shí)間歇運(yùn)動(dòng)的功能,涉及javascript定時(shí)器、數(shù)學(xué)運(yùn)算及頁(yè)面元素動(dòng)態(tài)修改的相關(guān)操作技巧,需要的朋友可以參考下2016-12-12
javascript 判斷數(shù)組是否已包含了某個(gè)元素的函數(shù)
javascript判斷數(shù)組是否已包含了某個(gè)元素的js函數(shù),方便數(shù)組的判斷。2010-05-05
自己寫(xiě)一個(gè)uniapp全局彈窗(APP端)
應(yīng)用uni-app跨平臺(tái)框架進(jìn)行項(xiàng)目開(kāi)發(fā)過(guò)程中,需要實(shí)現(xiàn)版本更新時(shí)全頁(yè)面彈窗,底部導(dǎo)航欄無(wú)法點(diǎn)擊的效果,下面這篇文章主要給大家介紹了關(guān)于uniapp全局彈窗(APP端)的相關(guān)資料,需要的朋友可以參考下2022-10-10
盤(pán)點(diǎn)javascript 正則表達(dá)式中 中括號(hào)的【坑】
下面小編就為大家?guī)?lái)一篇盤(pán)點(diǎn)javascript 正則表達(dá)式中 中括號(hào)的【坑】。小編覺(jué)得總結(jié)的不錯(cuò)?,F(xiàn)在分享給大家,希望能給大家一個(gè)參考2016-03-03
ES6新特性:使用export和import實(shí)現(xiàn)模塊化詳解
本篇文章主要介紹了ES6新特性:使用export和import實(shí)現(xiàn)模塊化詳解,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07

