MST

星途 面试题库

面试题:并发与同步:互斥锁在多线程环境下的应用原理

在一个多线程的程序中,有多个线程需要访问共享资源。请简述如何使用互斥锁来确保共享资源的安全访问,并且说明互斥锁的加锁和解锁操作在代码层面是如何体现的,以C++ 或Java语言为例进行说明。
45.4万 热度难度
操作系统并发与同步

知识考点

AI 面试

面试题答案

一键面试

C++ 示例

在C++ 中,可以使用<mutex>库来实现互斥锁。以下是一个简单的示例:

#include <iostream>
#include <mutex>
#include <thread>

std::mutex mtx;
int sharedResource = 0;

void increment() {
    for (int i = 0; i < 10000; ++i) {
        mtx.lock(); // 加锁
        ++sharedResource;
        mtx.unlock(); // 解锁
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

    t1.join();
    t2.join();

    std::cout << "Final value of shared resource: " << sharedResource << std::endl;
    return 0;
}

在上述代码中,std::mutex mtx 声明了一个互斥锁。mtx.lock() 用于加锁,当一个线程执行到这一行时,它会尝试获取锁。如果锁可用,该线程会获得锁并继续执行后续代码;如果锁不可用,该线程会被阻塞,直到锁被其他线程释放。mtx.unlock() 用于解锁,当线程完成对共享资源的操作后,调用此函数释放锁,以便其他线程可以获取锁来访问共享资源。

Java 示例

在Java中,可以使用synchronized关键字来实现类似互斥锁的功能。以下是一个示例:

class SharedResource {
    private int value = 0;

    public synchronized void increment() {
        for (int i = 0; i < 10000; ++i) {
            value++;
        }
    }

    public int getValue() {
        return value;
    }
}

public class Main {
    public static void main(String[] args) {
        SharedResource sharedResource = new SharedResource();

        Thread t1 = new Thread(() -> {
            sharedResource.increment();
        });

        Thread t2 = new Thread(() -> {
            sharedResource.increment();
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Final value of shared resource: " + sharedResource.getValue());
    }
}

在Java中,synchronized关键字可以用于方法或者代码块。在上述示例中,public synchronized void increment() 表示该方法是同步的,当一个线程进入这个方法时,它会自动获取对象的锁(这里是sharedResource对象的锁),相当于加锁操作。当方法执行完毕或者遇到异常时,会自动释放锁,相当于解锁操作。这样就确保了在同一时间只有一个线程能够访问increment方法中的共享资源value