When protecting shared resources across multiple threads, developers will generally reach for a “mutex.” As a refresher; a mutex is a type of object which ‘protects’ a resource, ensuring it is only accessed by a single consumer at a time; all other consumers are forced to wait in line. They must wait for the original consumer to release the mutex, before someone else can use it.
Think of a mutex like a key; you can only access the ‘locked’ resource as long as you’re holding the key. If someone else holds the key, you have to wait for them to put it down before you can pick it up.
With this in mind, it should go without saying that a mutex should generally be held only for the minimum amount of time absolutely necessary. When acquiring a mutex, users are encouraged to quickly finish their work so they can release the mutex to another consumer who might be waiting in line.
To some extent, this depends greatly on the shared ‘resource’ in question. For a shared queue, it’s easy to quickly acquire a mutex, ‘pop’ the top item off the stack, and release the mutex – all without the user’s awareness. For other resources however, consumers may need to hold a mutex for an extended period of time, through a series of complex operations.
For example: a connected “instrument” – such as a robot arm, or stepper motor – may need to be ‘reserved’ by a consumer for an extended period of time. It may need to perform many complex operations before the consumer is ready to release the mutex for someone else to use.
In cases like these, it is dangerous to rely on the consumer of a resource to reliably lock and unlock the mutex themselves. It would be so much more convenient and safe, if we could somehow package the resource and the mutex together, ensuring that one is always included with the other.
Enter the “lease” object.