Search code examples
javamultithreadinggroovysemaphorekey-value-store

Java Implement locking mechanism with persistent storage


I have implemented Groovy / Java JAR file with methods to install apps on mobile devices as well as get properties of the apps installed on a mobile device and the properties of a device.

I would like to implement a read and write locking mechanism that allows only a certain number of users access to a device. The write lock would be: 1 request per mobile device and for a read lock 10 requests per mobile device.

Java Semaphore seems like a good way to solve this allowing a number of requests allocated for a read and write lock. But I also need to store the states of each lock acquired against each device persistently.

Any advice on how to do this even without Semaphores would be appreciated. I anticipate less than 50 devices and less than 100 concurrent user requests.


Solution

  • You can use ReentrantReadWriteLock with BlockingQueue. ReentrantReadWriteLock is used to allow one writer, while BlockingQueue limits N readers to read at the same time. Something like this:

    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class DeviceHandler
    {
        private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
        private BlockingQueue<Object> readersQueue = new ArrayBlockingQueue<>(10);
    
        public void read() throws InterruptedException
        {
            // if queue is full, this blocks until another thread removes an object
            readersQueue.put(new Object());
            // this blocks if another thread acquires the write lock
            reentrantReadWriteLock.readLock().lock();
    
            // do read action
    
            reentrantReadWriteLock.readLock().unlock();
            readersQueue.take();
        }
    
        public void write()
        {
            // this blocks if the read lock is acquired by other threads
            reentrantReadWriteLock.writeLock().lock();
    
            // do write action
    
            reentrantReadWriteLock.writeLock().unlock();
        }
    }