MST

星途 面试题库

面试题:网络编程里异步编程模型在Web开发中如何解决资源竞争问题

当多个异步任务在Web开发中同时访问和修改共享资源时,会产生资源竞争问题。请说明在异步编程模型下,如何利用锁机制、信号量或者其他同步工具来确保数据的一致性和操作的原子性,并举出实际代码示例(可选用熟悉的编程语言)。
24.6万 热度难度
后端开发网络编程

知识考点

AI 面试

面试题答案

一键面试

1. 锁机制(以Python为例)

在Python中,threading模块提供了Lock类来实现锁机制。当一个线程获取到锁后,其他线程必须等待锁被释放才能获取锁并执行相关操作。

import threading

# 共享资源
shared_variable = 0
lock = threading.Lock()

def increment():
    global shared_variable
    with lock:
        shared_variable += 1

threads = []
for _ in range(10):
    t = threading.Thread(target=increment)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print(shared_variable)

2. 信号量(以JavaScript为例)

在JavaScript中,虽然没有像其他语言那样原生的信号量,但可以通过async/await结合Promise来模拟信号量。以下是一个简单的模拟信号量控制并发数的例子。

class Semaphore {
    constructor(initial) {
        this.count = initial;
        this.queue = [];
    }
    acquire() {
        return new Promise((resolve) => {
            if (this.count > 0) {
                this.count--;
                resolve();
            } else {
                this.queue.push(resolve);
            }
        });
    }
    release() {
        if (this.queue.length > 0) {
            this.queue.shift()();
        } else {
            this.count++;
        }
    }
}

// 模拟共享资源
let sharedResource = 0;
const semaphore = new Semaphore(1);

async function increment() {
    await semaphore.acquire();
    sharedResource++;
    semaphore.release();
}

const tasks = Array.from({ length: 10 }, () => increment());

Promise.all(tasks).then(() => {
    console.log(sharedResource);
});

3. 其他同步工具(以Java为例,使用CountDownLatch

CountDownLatch允许一个或多个线程等待,直到其他线程完成一组操作。

import java.util.concurrent.CountDownLatch;

public class SharedResourceExample {
    private static int sharedVariable = 0;
    private static final CountDownLatch latch = new CountDownLatch(10);

    public static void main(String[] args) {
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(() -> {
                synchronized (SharedResourceExample.class) {
                    sharedVariable++;
                }
                latch.countDown();
            });
            threads[i].start();
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(sharedVariable);
    }
}

以上代码示例分别展示了在Python、JavaScript和Java中如何利用锁机制、模拟信号量以及CountDownLatch来确保异步任务中共享资源操作的原子性和数据一致性。