org.eclipse.che.commons.lang.concurrent.StripedLocks.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.che.commons.lang.concurrent.StripedLocks.java

Source

/*******************************************************************************
 * Copyright (c) 2012-2017 Codenvy, S.A.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Codenvy, S.A. - initial API and implementation
 *******************************************************************************/
package org.eclipse.che.commons.lang.concurrent;

import com.google.common.util.concurrent.Striped;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * Helper class to use striped locks in try-with-resources construction.
 * </p>
 * Examples of usage:
 * <pre>{@code
 *  StripedLocks stripedLocks = new StripedLocks(16);
 *  try (Unlocker u = stripedLocks.writeLock(myKey)) {
 *      syncedObject.write();
 *  }
 *
 *  try (Unlocker u = stripedLocks.readLock(myKey)) {
 *      syncedObject.read();
 *  }
 *
 *  try (Unlocker u = stripedLocks.writeAllLock(myKey)) {
 *      for (ObjectToSync objectToSync : allObjectsToSync) {
 *          objectToSync.write();
 *      }
 *  }
 * }</pre>
 *
 * @author Alexander Garagatyi
 * @author Sergii Leschenko
 * @author Yevhenii Voevodin
 */
public class StripedLocks {

    private final Striped<ReadWriteLock> striped;

    public StripedLocks(int stripesCount) {
        striped = Striped.readWriteLock(stripesCount);
    }

    /**
     * Acquire read lock for provided key.
     */
    public Unlocker readLock(String key) {
        Lock lock = striped.get(key).readLock();
        lock.lock();
        return new LockUnlocker(lock);
    }

    /**
     * Acquire write lock for provided key.
     */
    public Unlocker writeLock(String key) {
        Lock lock = striped.get(key).writeLock();
        lock.lock();
        return new LockUnlocker(lock);
    }

    /**
     * Acquire write lock for all possible keys.
     */
    public Unlocker writeAllLock() {
        Lock[] locks = getAllWriteLocks();
        for (Lock lock : locks) {
            lock.lock();
        }
        return new LocksUnlocker(locks);
    }

    private Lock[] getAllWriteLocks() {
        Lock[] locks = new Lock[striped.size()];
        for (int i = 0; i < striped.size(); i++) {
            locks[i] = striped.getAt(i).writeLock();
        }
        return locks;
    }

    private static class LockUnlocker implements Unlocker {

        private final Lock lock;

        private LockUnlocker(Lock lock) {
            this.lock = lock;
        }

        @Override
        public void unlock() {
            lock.unlock();
        }
    }

    private static class LocksUnlocker implements Unlocker {

        private final Lock[] locks;

        private LocksUnlocker(Lock[] locks) {
            this.locks = locks;
        }

        @Override
        public void unlock() {
            for (Lock lock : locks) {
                lock.unlock();
            }
        }
    }
}