★★★★★JS的同步问题(以经典的生产者-消费者为例)

时间:2022-04-21 16:41:53
做完JS版俄斯方块后回想……

<input type="button" onClick="clearInterval(Timer1);clearInterval(Timer2);" value="stop">
<input type="button" onClick="Timer1=setInterval('producer()', pspeed);Timer2=setInterval('consumer()', cspeed);" value="start">
<div id="d"></div>
<script>
var i = 0,  j = 0; 
var pspeed = 1000, cspeed = 1000;
function producer()
{
i ++;
for (k=0; k<1000000; k++) ;
j ++;
}

function consumer()
{
d.innerHTML += j + " ";
for (k= 0; k<1000000; k++) ;
d.innerHTML += i+ "<br>";
}
var Timer1 = setInterval("producer()", pspeed);
var Timer2 = setInterval("consumer()", cspeed);
</script>

上面的输出结果
1 1
1 1
3 3
3 3
5 5
5 5
7 7
……
很明显的可以看出,javascript并不可能会出现多线程,因此i和j的值永远都是一致的

请教高手:为什么上面的代码都是一个函数执行两次轮替,而不会出现一次就轮换,JS中代码执行有优先权吗?

25 个解决方案

#1


既然是单线程,哪有什么优先权的说法

#2


当然有了,否则你用什么来解释上述现象,两个同时的setInterval却会轮换着被先执行

或者这个不应该叫做优先权,但是代码执行确实是应该有个顺序和规则的

#3


希望看到高手的解释,没有什么分了,它不长没法子

#4


参与一下,考虑考虑先。

#5


再顶顶,百思不得其解!
希望各位朋友帮助……我也再想想。

#6


贴子已加上100分(老本都贴上了),请大家不吝赐教

#7


关注~

#8


把pspeed 的赋为500则是
1 1
3 3
5 5
7 7
......

#9


我的执行结果

1 1
1 1
3 3
4 4
4 4
5 5
7 7
8 8
8 8
9 9
11 11
12 12
12 12
13 13
15 15
15 15
17 17
17 17
19 19
19 19

#10


这一行;

var pspeed = 1000, cspeed = 1000;

如果,你把pspeed和cspeed的初值设为不一样的值,便不会出现两次轮替。。。。

#11


awaysrain(绝对零度)(新的一年,新的开始) 用的什么CPU,推荐一下

我的试过N次都是前面那个结果,真是郁闷

#12


BlueDestiny(蓝色||命运)你的想法和本题无关,请抬头--同步问题

#13


result

 
1 1
1 1
3 3
4 4
4 4
5 5
7 7
8 8
8 8
9 9
11 11
12 12
12 12
13 13
15 15
16 16
16 16
17 17
19 19
20 20
20 20
21 21
23 23
24 24
24 24
25 25
27 27
28 28
28 28
30 30
30 30
32 32
32 32
34 34

#14


我再帮忙顶一顶。尝试将代码转为VBS,结果一样。
不过,我发现:我有两次运行发生了“意外”,其中一次是完全顺序输出,另一次是大概到了30多以后就顺序输出……仅仅只有两次,关键代码没有改动,不明白原因。
——感觉像UFO,最近X-FILES看多了。

#15


请大家把各自的CPU报上,怀疑和CPU有关,呵呵

#16


我把代码改成了这样:
<span id=d></span>
<script>
function producer(i)
{
d.innerHTML = d.innerHTML + i + "<br/>"
}
setInterval("producer(1)",1000)
setInterval("producer(2)",1000)
setInterval("producer(3)",1000)
</script>
然后,(假设的)“指令指针”顺着producer(1~3)来回移动。
——只有在间隔时间相同的情况下才会这样。

……未完待续

#17


PIII 500

接着,对三个setInterval施加一些“干扰”,如下:
setInterval("producer(1)",1000)
setInterval("producer(2)",1000)
for(j=0;j<10000;j++);
setInterval("producer(3)",1000)

就会发现,结果出现了改变。

看来,存在“计算能源消耗问题”(我自己编的词汇)!接着做以下实验!

……未完待续

#18


接着将干扰setInterval()用的for循环终值改为100,就会发现,“干扰”失效了。
——由此看来,好像CPU的确有点责任。

继续做实验,希望把相同间隔的setInterval()的运行规律找出来!

……未完待续

#19


也许这是一个先进后出的堆栈:对于同一个cpu时刻内推入定时器的队列(并且动作的定时间隔相同的才推入同一个堆栈),则下一次执行的顺序会倒过来:

setInterval("producer()", pspeed);
setInterval("consumer()", cspeed);

>>>>>
producer();
consumer();

consumer();
producer();

producer();
consumer();

consumer();
producer();

...........

仅仅是猜测,没有找到切实证据,呵呵

#20


的确能用“先进先出”来解释……

#21


我的CPU是奔三667超到750

#22


唉。





_____________________________________________________________________________

该问题已经结贴 ,得分记录:  zairwolfc (300)

#23


楼上最近到处搞笑啊?
我也到这里来接一点分,呵呵。

说实在的,为什么我当初没有想到先进先出原则呢?失算。
——OH,My X-Files!

#24


都说了,是单线程,栈存储 两重原因的!

#25


今天收到国外某强人的E-MAIL(询问这个问题的回复)。
他的回答还真是明确:
1、他不知道IE是如何实现setInterval()的,但不同的浏览器甚至不同的版本,实现方法可能改变(言外之意是这个问题没有实际意义)。
2、不应该像这样使用setInterval(),完全是自找麻烦。
——虽然这样的回答让我不满意,不过我还是回信向他表示感谢了。外国人都那么实际?

#1


既然是单线程,哪有什么优先权的说法

#2


当然有了,否则你用什么来解释上述现象,两个同时的setInterval却会轮换着被先执行

或者这个不应该叫做优先权,但是代码执行确实是应该有个顺序和规则的

#3


希望看到高手的解释,没有什么分了,它不长没法子

#4


参与一下,考虑考虑先。

#5


再顶顶,百思不得其解!
希望各位朋友帮助……我也再想想。

#6


贴子已加上100分(老本都贴上了),请大家不吝赐教

#7


关注~

#8


把pspeed 的赋为500则是
1 1
3 3
5 5
7 7
......

#9


我的执行结果

1 1
1 1
3 3
4 4
4 4
5 5
7 7
8 8
8 8
9 9
11 11
12 12
12 12
13 13
15 15
15 15
17 17
17 17
19 19
19 19

#10


这一行;

var pspeed = 1000, cspeed = 1000;

如果,你把pspeed和cspeed的初值设为不一样的值,便不会出现两次轮替。。。。

#11


awaysrain(绝对零度)(新的一年,新的开始) 用的什么CPU,推荐一下

我的试过N次都是前面那个结果,真是郁闷

#12


BlueDestiny(蓝色||命运)你的想法和本题无关,请抬头--同步问题

#13


result

 
1 1
1 1
3 3
4 4
4 4
5 5
7 7
8 8
8 8
9 9
11 11
12 12
12 12
13 13
15 15
16 16
16 16
17 17
19 19
20 20
20 20
21 21
23 23
24 24
24 24
25 25
27 27
28 28
28 28
30 30
30 30
32 32
32 32
34 34

#14


我再帮忙顶一顶。尝试将代码转为VBS,结果一样。
不过,我发现:我有两次运行发生了“意外”,其中一次是完全顺序输出,另一次是大概到了30多以后就顺序输出……仅仅只有两次,关键代码没有改动,不明白原因。
——感觉像UFO,最近X-FILES看多了。

#15


请大家把各自的CPU报上,怀疑和CPU有关,呵呵

#16


我把代码改成了这样:
<span id=d></span>
<script>
function producer(i)
{
d.innerHTML = d.innerHTML + i + "<br/>"
}
setInterval("producer(1)",1000)
setInterval("producer(2)",1000)
setInterval("producer(3)",1000)
</script>
然后,(假设的)“指令指针”顺着producer(1~3)来回移动。
——只有在间隔时间相同的情况下才会这样。

……未完待续

#17


PIII 500

接着,对三个setInterval施加一些“干扰”,如下:
setInterval("producer(1)",1000)
setInterval("producer(2)",1000)
for(j=0;j<10000;j++);
setInterval("producer(3)",1000)

就会发现,结果出现了改变。

看来,存在“计算能源消耗问题”(我自己编的词汇)!接着做以下实验!

……未完待续

#18


接着将干扰setInterval()用的for循环终值改为100,就会发现,“干扰”失效了。
——由此看来,好像CPU的确有点责任。

继续做实验,希望把相同间隔的setInterval()的运行规律找出来!

……未完待续

#19


也许这是一个先进后出的堆栈:对于同一个cpu时刻内推入定时器的队列(并且动作的定时间隔相同的才推入同一个堆栈),则下一次执行的顺序会倒过来:

setInterval("producer()", pspeed);
setInterval("consumer()", cspeed);

>>>>>
producer();
consumer();

consumer();
producer();

producer();
consumer();

consumer();
producer();

...........

仅仅是猜测,没有找到切实证据,呵呵

#20


的确能用“先进先出”来解释……

#21


我的CPU是奔三667超到750

#22


唉。





_____________________________________________________________________________

该问题已经结贴 ,得分记录:  zairwolfc (300)

#23


楼上最近到处搞笑啊?
我也到这里来接一点分,呵呵。

说实在的,为什么我当初没有想到先进先出原则呢?失算。
——OH,My X-Files!

#24


都说了,是单线程,栈存储 两重原因的!

#25


今天收到国外某强人的E-MAIL(询问这个问题的回复)。
他的回答还真是明确:
1、他不知道IE是如何实现setInterval()的,但不同的浏览器甚至不同的版本,实现方法可能改变(言外之意是这个问题没有实际意义)。
2、不应该像这样使用setInterval(),完全是自找麻烦。
——虽然这样的回答让我不满意,不过我还是回信向他表示感谢了。外国人都那么实际?