Using different instances of an object to lock threads
Your code would do just fine, in terms of functionality.

However, note that such design holds as long as everybody knows that they should acquire the lock before performing any process on the person object.

Perhaps you should consider re-design your data objects (such as the person class) so that there's an explicit method for any update process. Perhaps something like BeginEdit and EndEdit, or, even better, a method that returns an IDisposable object that acquires the lock and releases it in its Dispose implementation. Example:

public class Person {
    public IDisposable AcquireLock() {
        // ...
    }

    // ...
}

// usage:
var aPerson = GetPerson(1234);
using (aPerson.AcquireLock()) {
    aPerson.LastName = "abcd";
    SavePerson(aPerson);
    // ...
}


This way the locking is made more explicit.

Just a suggestion, though...