在编程的路上,我一直都是“代码就是生命”的信徒。
最近,我的面试之路有点坎坷,尤其是遇到面试官抛出的一个经典难题:“假如有几十个请求,如何去控制并发?”
这道题不仅让我的脑子里立刻浮现出了一场激烈的并发战争,还让我意识到,掌握并发控制技巧是多么重要。
今天,我将分享一下我是如何一步步解决这个问题的。
什么是并发
并发(Concurrency)是指在同一时间段内执行多个任务的能力。
在单核处理器上,并发任务会快速切换执行,从而使得多个任务看起来同时运行;而在多核处理器上,并发任务则可以真正地同时执行。
为什么需要控制并发
虽然并发可以提高程序的效率和响应速度,但如果不加以控制,很容易造成资源竞争、死锁、系统过载等问题。
因此,在处理大量并发请求时,必须合理地控制并发数量,以保证系统的稳定性和性能。
常见的并发控制方法
常见的并发控制方法包括:
- 1. 限流(Rate Limiting):限制在一定时间内允许通过的请求数量。
- 2. 信号量(Semaphore):使用信号量来控制并发执行的数量。
- 3. 队列(Queue):使用队列将请求按顺序排队处理。
- 4. 线程池(Thread Pool):使用线程池来限制并发执行的线程数量。
使用 JavaScript 实现并发控制
Promise.all 示例
在 JavaScript 中,可以使用 Promise.all
来处理多个并发请求。以下是一个简单的示例:
const fetch = require('node-fetch'); const urls = [ 'https://jsonplaceholder.typicode.com/posts/1', 'https://jsonplaceholder.typicode.com/posts/2', 'https://jsonplaceholder.typicode.com/posts/3', // ... 更多 URL ]; function limitConcurrency(urls, limit) { const results = []; const executing = []; async function enqueue() { if (urls.length === 0) return Promise.resolve(); const url = urls.shift(); const promise = fetch(url).then(response => response.json()); results.push(promise); const e = promise.then(() => executing.splice(executing.indexOf(e), 1)); executing.push(e); let r = Promise.resolve(); if (executing.length >= limit) { r = Promise.race(executing); } await r; return enqueue(); } return enqueue().then(() => Promise.all(results)); } limitConcurrency(urls, 2) .then(results => { console.log('所有请求完成:', results); }) .catch(error => { console.error('请求失败:', error); });
并发限制示例
使用 Promise.all
时,如果请求数量非常多,可能会导致资源耗尽问题。可以通过自定义并发控制函数来限制并发请求的数量。以下是一个示例:
const fetch = require('node-fetch'); const urls = [ 'https://jsonplaceholder.typicode.com/posts/1', 'https://jsonplaceholder.typicode.com/posts/2', 'https://jsonplaceholder.typicode.com/posts/3', // ... 更多 URL ]; function limitConcurrency(urls, limit) { const results = []; const executing = []; async function enqueue() { if (urls.length === 0) return Promise.resolve(); const url = urls.shift(); const promise = fetch(url).then(response => response.json()); results.push(promise); const e = promise.then(() => executing.splice(executing.indexOf(e), 1)); executing.push(e); let r = Promise.resolve(); if (executing.length >= limit) { r = Promise.race(executing); } await r; return enqueue(); } return enqueue().then(() => Promise.all(results)); } limitConcurrency(urls, 2) .then(results => { console.log('所有请求完成:', results); }) .catch(error => { console.error('请求失败:', error); });
总结
合理地控制并发不仅可以提高程序的效率,还能保证系统的稳定性和安全性。
希望通过本文的介绍,你能在实际项目中灵活运用这些技巧,解决并发控制的问题。