基于Semaphore实现影院场景多线程共享资源访问的正确性咨询
Great job putting together this practical example of using a Counting Semaphore—let’s dive into your questions:
1. Does this implementation align with Semaphore's design goals?
Absolutely! Counting Semaphores are explicitly designed to control the number of threads that can access a shared resource or perform a concurrent operation at the same time, which is exactly what you’ve done here:
- You’ve initialized a
Semaphorewith a permit count of 2, which correctly enforces the rule that only 2 "audience members" (threads) can enter the theater (shared resource) at once. - You’re using the core Semaphore APIs correctly:
available.acquire(): Threads must obtain a permit before accessing the shared resource (entering the theater), which blocks if no permits are available.available.release(): When a thread is done with the resource (leaves the theater), it releases its permit, allowing a waiting thread to take it.
- The fair mode (
truein the constructor) is a nice touch—it ensures threads are granted permits in the order they requested them, preventing thread starvation, which aligns with Semaphore's flexibility to support both fair and non-fair access.
2. Does it correctly simulate multi-threaded access to a shared resource?
Yes, your theater/audience scenario is a perfect analogy for this use case, and your code implements it correctly:
- The theater is clearly the shared limited resource, with a fixed capacity of 2.
- You’ve handled concurrency visibility correctly: The
volatilemodifier onPerson.moveOutensures that when the main thread updates this value, theMovieWatchingthread sees the latest value immediately—avoiding the infinite loop that would occur without proper visibility guarantees. - Your test flow in
MainDemovalidates the behavior:- Threads t1 and t2 enter first (since permits are available).
- Thread t3 waits until t1 releases a permit, then enters—your sample output confirms this exact sequence.
Small Suggestions to Polish the Implementation
While your code works as intended, here are a few tweaks to make it more robust and realistic:
- Replace the empty loop in
watchMoviewith a smallThread.sleep()(e.g.,Thread.sleep(100)) to simulate actual "movie watching" work—empty loops waste CPU cycles unnecessarily. - Consider using
AtomicBooleaninstead ofvolatile BooleanformoveOut; while volatile works here,AtomicBooleanis purpose-built for atomic operations in concurrent contexts and makes the intent clearer. - In the
Person.run()method, instead of just printing the stack trace forInterruptedException, you could re-set the thread's interrupted status withThread.currentThread().interrupt()—this preserves the interrupt signal for any upstream code that might need it.
Overall, this is a solid first implementation of a Counting Semaphore—you’ve nailed the core concepts and applied them to a relatable real-world scenario!
内容的提问来源于stack exchange,提问作者CuriousMind

