interview
java-concurrency
什么是Java的Semaphore?

Java并发面试题, 什么是 Java 的 Semaphore?

Java并发面试题, 什么是 Java 的 Semaphore?

QA

Step 1

Q:: 什么是 Java 的 Semaphore?

A:: Java 的 Semaphore 是一种同步工具,用来控制同时访问某特定资源的线程数量。它允许多个线程同时访问一组资源,但控制同时访问的线程数目,通过 acquire() 和 release() 方法来实现资源的获取和释放。

Step 2

Q:: Semaphore 的构造方法有哪些?

A:: Semaphore 的构造方法主要有两个:Semaphore(int permits) 和 Semaphore(int permits, boolean fair)。第一个构造方法创建一个指定许可数量的非公平信号量,第二个构造方法可以指定公平性,若 fair 参数为 true,则信号量会按照 FIFO (先到先得) 原则处理线程的请求。

Step 3

Q:: 如何使用 Semaphore 实现限流?

A:: 限流是通过控制并发量来防止系统过载的一种方式。Semaphore 可以通过指定同时允许访问的最大线程数来实现限流。例如,创建一个 Semaphore(5) 对象,表示最多允许 5 个线程同时访问某个资源。每个线程在访问资源前调用 acquire() 方法,在访问后调用 release() 方法,从而控制并发数量。

Step 4

Q:: Semaphore 和 ReentrantLock 的区别是什么?

A:: Semaphore 和 ReentrantLock 都可以用于线程同步,但它们有以下区别:1. Semaphore 控制的是访问资源的线程数量,可以同时允许多个线程访问;而 ReentrantLock 仅允许一个线程持有锁。2. Semaphore 提供的 acquire() 和 release() 方法可以用于限流;而 ReentrantLock 提供的是独占锁。3. Semaphore 可以用来实现资源池;而 ReentrantLock 则更多用于保护单个资源的独占访问。

Step 5

Q:: Semaphore 的公平模式和非公平模式有什么区别?

A:: 公平模式 (fair) 和非公平模式 (non-fair) 是 Semaphore 两种工作模式。公平模式下,线程会按照 FIFO (先到先得) 顺序获得许可;非公平模式下,线程获取许可的顺序是随机的,可能会导致某些线程长期等待。

用途

面试这个内容的目的是为了评估候选人对 Java 并发编程的理解和实际应用能力。Semaphore 在生产环境中常用于限流、资源池管理和多线程任务调度等场景。例如,在高并发的 Web 服务中,可以通过 Semaphore 来控制同时处理请求的线程数量,防止服务器过载。\n

相关问题

🦆
什么是 Java 的 volatile 关键字?

volatile 是一种轻量级的同步机制,用于确保变量的可见性。当一个变量被声明为 volatile 时,所有线程在访问该变量时都会直接从主内存中读取,保证变量的最新值对所有线程可见。

🦆
Java 中的 CountDownLatch 是什么?

CountDownLatch 是一个同步工具类,用来协调多个线程之间的同步。它允许一个或多个线程等待,直到其他线程完成一系列操作。通过调用 countDown() 方法递减计数器,当计数器减为 0 时,所有等待的线程会被唤醒。

🦆
什么是 Java 中的 CyclicBarrier?

CyclicBarrier 是一个同步辅助类,允许一组线程互相等待,直到所有线程都到达一个共同的屏障点。可以通过指定的参与线程数量和一个可选的 barrierAction 操作来创建 CyclicBarrier,当所有线程都到达屏障点时,barrierAction 会被执行。

🦆
ReentrantLock 和 synchronized 的区别是什么?

ReentrantLock 和 synchronized 都用于实现线程同步,但它们有一些区别:1. ReentrantLock 是一个显式锁,可以手动锁定和释放,而 synchronized 是隐式锁,使用代码块或方法的形式。2. ReentrantLock 提供更多的功能,如可中断锁定、尝试锁定、定时锁定等;而 synchronized 则较为简单。3. ReentrantLock 支持公平锁和非公平锁,而 synchronized 只能是非公平锁。

🦆
什么是 Java 中的 Exchanger?

Exchanger 是一个用于线程间数据交换的同步点。它允许两个线程在某个同步点交换数据。每个线程在到达同步点时,会等待另一个线程到达,然后进行数据交换。通过 exchange() 方法实现数据交换。