js怎么处理高并发

JavaScript012

js怎么处理高并发,第1张

JS不同于Java, C#等语言.

使用Java编写的应用, 可以编程开启多线程处理高并发业务场景.

而JS处理高并发场景使用的是 : 队列机制, 事件机制

因为JS在网页中运行时单线程模式, 在服务端nodejs中运行是单进程模式, 都无法像JAVA那样开启多个线程或者协程来处理高并发任务.

但是这不意味着JS无法处理高并发任务, 单进程的程序在使用队列机制(就是待处理任务一个个排队)处理高并发场景也仍然是非常高效的, 而且避免了开启多个线程的内存消耗.但是其缺点也是很明显的 : 不适合处理单个任务计算非常复杂消耗时间的场景.

举个栗子 :

想象一下生活中排队的场景, 如果前面有一个人磨磨唧唧, 半天赖在窗口各种问问题, 后面的人都要排队等着, 很着急.

而如果开启多个窗口(多线程/进程), 那些难缠的人分到一个窗口, 速度快的人分到一个窗口, 效率就大大提升了.

JS本身是为GUI而生的语言,GUI生而是多线程的,但生而也是单线程的。因为竞争访问的问题,只有一个UI线程是一种安全的方式。比如C# WinForm中只允许一个线程访问GUI,其他线程需要以委托的形式来访问GUI。

JS曾经在Web GUI中表现良好,因为过去的Web GUI规模小,只要注意一些写法问题,不太容易遇到阻塞UI线程的问题,直到应用程序变复杂了才开始注意到这些问题。浏览器变得更快一定程度上延缓了这些问题,但是终究还是对并发的需求越来越大。

WebWorker是真多线程——当然我是说从实现上讲,它是多个线程,至于楼主所说的,没有共享全局变量、没有锁,我觉得没有必要太纠结。多线程是一种并发模型,并且也许是受众最广泛的一种。WebWorker用的是基于通讯的并发模型,类似于erlang、Go,用的是Share Nothing的哲学(虽然终究还是有SharedArrayBuffer),它们都是经过了工业级别考验的。

有了share那么必然会有竞争访问,于是就有了锁,这些都是自然而然的。但是,很明显,JS的发展倾向于share nothing,不然就干脆把整个global对象share了算了。

至于为什么留SharedArrayBuffer,我觉得这只能说是“给不给”这个东西,不是“要不要”这样用了。这就和Go有点像了,应为闭包的存在GoRoutine之间也可以share,于是它也提供了锁,提供了mutex,但是它所建议的哲学还是用channel,用CSP,于是大家通常也都还是这么用。用GoRoutine当线程用,让channel滚蛋,还是用锁,还是可以做并发编程啊,但是好像没人这么弄吧,哈哈。

多线程只是手段,并发才是目的,只要能实现目的,手段就是个方法论而已。

至于多线程和异步之间我感觉没有太直接的绑定关系吧,单线程可以异步,多线程也可以同步。

如果JS一开始就具有多线程的话,现今JS程序员可能会少一半吧(笑

单线程解决高并发的思路就是采用非阻塞,异步编程的思想。简单概括就是当遇到非常耗时的IO操作时,采用非阻塞的方式,继续执行后面的代码,并且进入事件循环,当IO操作完成时,程序会被通知IO操作已经完成。主要运用JavaScript的回调函数来实现。

多线程虽然也能解决高并发,但是是以建立多个线程来实现,其缺点是当遇到耗时的IO操作时,当前线程会被阻塞,并且把cpu的控制权交给其他线程,这样带来的问题就是要非常频繁的进行线程的上下文切换。