信号量(Semaphore)和互斥量(Mutex)都是用于控制对共享资源的访问以避免并发冲突的同步机制,但它们在概念和用途上有所区别。

信号量(Semaphore):

  • 信号量可以有多个许可,这意味着它可以允许多个线程同时访问同一资源或资源池。
  • 信号量主要用于限制对资源的访问数量,不一定保证线程安全,需要开发者自己控制。
  • 信号量通常用于实现资源池,如数据库连接池,或限制容器的容量,如Semaphore可用于限制执行的线程数目。

互斥量(Mutex):

  • 互斥量是一个特殊类型的信号量,一次只允许一个线程持有,即它的许可数量限制为1。
  • 互斥量提供了所有权的概念,只有锁的持有者能够释放锁,而信号量则没有所有权的概念,任何线程都可以释放。
  • 互斥量通常用于保护临界区,确保某一时间点只有一个线程可以进入临界区修改共享数据。

例子:

信号量(Semaphore)示例:

import java.util.concurrent.Semaphore;

public class ConnectionPool {
    private static final int MAX_AVAILABLE = 10;
    private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

    public Object getConnection() throws InterruptedException {
        available.acquire();
        try {
            // 获取数据库连接操作... 
            return fetchConnection();
        } finally {
            available.release();
        }
    } // 释放数据库连接回池的方法...

    public void releaseConnection(Object conn) {
        // 释放操作... 
        available.release();
    }

    private Object fetchConnection() {
        // 实际创建或重用一个数据库连接的代码... 
    }
}
此示例中,Semaphore设定有10个许可,代表一个能容纳10个连接的数据库连接池。

互斥量(Mutex)示例,通常在Java中通过ReentrantLock实现:

import java.util.concurrent.locks.ReentrantLock;

public class Counter {
    private int count = 0;
    private final ReentrantLock lock = new ReentrantLock();

    public void increment() {
        lock.lock(); // 获取锁 
        try {
            count++;
        } finally {
            lock.unlock();
            // 释放锁
        }
    }

    public int getCount() {
        return count;
    }
}

该示例中,我们使用ReentrantLock来保证在任何时刻只有一个线程能够修改count变量的值。在increment()方法中,当线程调用lock.lock()后,其他尝试调用increment()的线程会被阻塞直到锁被释放。

总结信号量用于控制同时访问资源的线程数量,而互斥量用于保证同一时间只有一个线程访问资源。

本篇文章来源于微信公众号: 互联网面试小帮手



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2024-08-02