Java实现对象级并发:对象级锁使用求助
Hey there! Let's walk through how to get your desired concurrency control working smoothly—since you're new to multi-threading, I'll keep things clear and practical.
First, let's restate your goal to make sure we're on the same page: You want the same user (i.e., the same Person instance) to be blocked from calling setAttendance and getAttendance at the same time. Different users should be able to run these methods concurrently without interfering with each other.
What's the Issue with Your Current Setup?
Right now, your Attendance class methods are marked synchronized, which locks the Attendance instance itself. This works if each Person has its own Attendance object (since each user's Attendance lock is separate), but it's not the most intuitive approach—and it falls short if your Person methods ever need to sync other logic beyond just calling Attendance methods. Worse, if multiple Persons share the same Attendance instance, this would lock all users out, which isn't what you want.
The Right Solution: Lock the Person Instance
Since your requirement is tied to the user (Person object), the cleanest way is to lock the Person instance directly. Here are two straightforward ways to do this:
Option 1: Use synchronized Methods on Person
Marking the Person methods as synchronized automatically uses the Person instance (this) as the lock. This ensures that only one method can run at a time for the same user:
public class Person { private Attendance attendance; public Person(Attendance attendance) { this.attendance = attendance; } // Synchronized on the Person instance public synchronized void setAttendance(String status) { // Add any other Person-specific logic here (it'll be thread-safe too) attendance.setAttendance(status); } // Synchronized on the same Person instance public synchronized String getAttendance() { return attendance.getAttendance(); } } public class Attendance { private String status; // You can keep these synchronized if you want extra safety, but it's not strictly necessary // since the Person methods already handle the locking for per-user access public synchronized void setAttendance(String status) { this.status = status; } public synchronized String getAttendance() { return status; } }
Option 2: Manual Lock with synchronized Blocks
If you only need to sync a portion of the method (instead of the whole thing), use a synchronized block that locks this (the Person instance):
public class Person { private Attendance attendance; public Person(Attendance attendance) { this.attendance = attendance; } public void setAttendance(String status) { // Only sync the critical section (including Attendance calls) synchronized(this) { attendance.setAttendance(status); // Any other thread-safe operations tied to this user go here } // Non-critical logic can run outside the block } public String getAttendance() { synchronized(this) { return attendance.getAttendance(); } } }
Key Notes to Remember
- Ensure One Person Instance Per User: This setup only works if each user maps to exactly one
Personobject. If you create a newPersonfor every request, the locks won't apply across requests for the same user. - Avoid Shared
AttendanceLocks: If multiplePersons share the sameAttendanceinstance, locking theAttendanceobject would block all users—stick to locking thePersoninstance to keep per-user isolation. - Keep Lock Scope Small: If you use synchronized blocks, only wrap the code that actually needs thread safety. This keeps your application more performant.
That should give you exactly the per-user mutex you're looking for! Let me know if you need clarification on any part.
内容的提问来源于stack exchange,提问作者vartika

