MST

星途 面试题库

面试题:自定义实现一个类似Java Semaphore功能的同步器

请你基于Java的多线程机制,自定义实现一个同步器,该同步器需要具备类似Java Semaphore的功能,包括获取许可、释放许可等操作,并说明实现过程中的关键要点。
48.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

自定义同步器实现

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class CustomSemaphore {
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private int permits;

    public CustomSemaphore(int initialPermits) {
        if (initialPermits < 0) {
            throw new IllegalArgumentException("Initial permits cannot be negative");
        }
        this.permits = initialPermits;
    }

    public void acquire() throws InterruptedException {
        lock.lock();
        try {
            while (permits <= 0) {
                condition.await();
            }
            permits--;
        } finally {
            lock.unlock();
        }
    }

    public void release() {
        lock.lock();
        try {
            permits++;
            condition.signal();
        } finally {
            lock.unlock();
        }
    }
}

关键要点

  1. 锁机制:使用ReentrantLock来保证对共享资源(许可数量permits)的线程安全访问。ReentrantLock提供了可重入的特性,并且可以替代synchronized关键字,提供更灵活的锁控制。
  2. 条件变量:通过lock.newCondition()创建Condition对象,用于线程的等待和唤醒。当许可数量不足时,线程通过condition.await()进入等待状态,当有许可被释放时,通过condition.signal()唤醒等待队列中的一个线程。
  3. 许可数量控制:使用一个整型变量permits来表示当前可用的许可数量。在acquire方法中,当许可数量大于0时,线程获取许可并将permits减1;在release方法中,每次释放许可时将permits加1。
  4. 异常处理:在acquire方法中,由于await方法会抛出InterruptedException,所以需要在方法声明中抛出该异常,或者在方法内部进行处理。这样可以确保在等待过程中如果线程被中断,能够及时做出响应。