昨天,今天,明天,每天的每天,你是否都多懂得一点点...

星期三, 九月 11, 2019

A simple javascript threading experiment with setTimeout

I am going to add a global queue object to my nodejs express program, then this raises a concern of thread safety. 

I am implementing a queue with only 10 elements, the older elements will be throw away.  So I wrote the following code to test. 

In the following code, the if (queue.length > 10) can cause problem. Because when both thread run into this block and both finish pushing the element,  we will have 12 elements in the queue.

For example
[12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]

The new elements in this queue is 22, and 23.

Now thread 1 will do a slice and make the queue to be 

  [13, 14, 15, 16, 17, 18, 19, 20, 21, 22]  

At this point, because the queue length is 10, then the thread 2 will not do the slice.  The pushed element 23 is gone. 

If thread 2 read the queue length before thread 1 slice it. Then thread 2 will slice it again. 

the array become 

 [14, 15, 16, 17, 18, 19, 20, 21, 22]

Only 9 element in the queue, 13 is gone.


[javascript]

let queue = [];
let threads = 100000;
for (let i = 0; i < threads; i++) {
    setTimeout(() => {
        queue.push(i);
        // This line can have a dirty read
        if (queue.length > 10) {
            queue = queue.slice (1, 11);
        }

        if (i >= threads - 10) {
            console.log(queue);
        }
    }, 1000);
}

[/javascript]

But when I tested this in the browser. it never failed. It's very interesting. 

A small improvement is using a temp variable to hold the original queue outside the if block, then use the temp var in the if block. It will make sure only 1 element will be missing.  

[javascript]

let queue = [];
let threads = 100000;
for (let i = 0; i < threads; i++) {
    setTimeout(() => {
        queue.push(i);
       let tempQueue = queue;
        // This line can have a dirty read
        if (queue.length > 10) {
            queue = tempQueue.slice (1, 11);
        }

        if (i >= threads - 10) {
            console.log(queue);
        }
    }, 1000);
}

[/javascript]


--
Feng

没有评论:

其它博客地址

此博客的同步博客地址: http://fengnz.wordpress.com
这里进入我的MSN SPACE.