001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.util.concurrent;
018
019import java.util.concurrent.Callable;
020import java.util.concurrent.locks.StampedLock;
021import java.util.function.Supplier;
022
023import org.apache.camel.util.function.ThrowingRunnable;
024import org.apache.camel.util.function.ThrowingSupplier;
025
026public final class LockHelper {
027    private LockHelper() {
028    }
029
030    public static void doWithReadLock(StampedLock lock, Runnable task) {
031        long stamp = lock.readLock();
032
033        try {
034            task.run();
035        } finally {
036            lock.unlockRead(stamp);
037        }
038    }
039
040    public static <R> R callWithReadLock(StampedLock lock, Callable<R> task) throws Exception {
041        long stamp = lock.readLock();
042
043        try {
044            return task.call();
045        } finally {
046            lock.unlockRead(stamp);
047        }
048    }
049
050    public static <T extends Throwable> void doWithReadLockT(StampedLock lock, ThrowingRunnable<T> task) throws T {
051        long stamp = lock.readLock();
052
053        try {
054            task.run();
055        } finally {
056            lock.unlockRead(stamp);
057        }
058    }
059
060    public static <R> R supplyWithReadLock(StampedLock lock, Supplier<R> task) {
061        long stamp = lock.readLock();
062
063        try {
064            return task.get();
065        } finally {
066            lock.unlockRead(stamp);
067        }
068    }
069
070    public static <R, T extends Throwable> R supplyWithReadLockT(StampedLock lock, ThrowingSupplier<R, T> task) throws T {
071        long stamp = lock.readLock();
072
073        try {
074            return task.get();
075        } finally {
076            lock.unlockRead(stamp);
077        }
078    }
079
080    public static void doWithWriteLock(StampedLock lock, Runnable task) {
081        long stamp = lock.writeLock();
082
083        try {
084            task.run();
085        } finally {
086            lock.unlockWrite(stamp);
087        }
088    }
089
090    public static <R> R callWithWriteLock(StampedLock lock, Callable<R> task) throws Exception {
091        long stamp = lock.writeLock();
092
093        try {
094            return task.call();
095        } finally {
096            lock.unlockWrite(stamp);
097        }
098    }
099
100    public static <R> R supplyWithWriteLock(StampedLock lock, Supplier<R> task) {
101        long stamp = lock.writeLock();
102
103        try {
104            return task.get();
105        } finally {
106            lock.unlockWrite(stamp);
107        }
108    }
109
110    public static <T extends Throwable> void doWithWriteLockT(StampedLock lock, ThrowingRunnable<T> task) throws T {
111        long stamp = lock.writeLock();
112
113        try {
114            task.run();
115        } finally {
116            lock.unlockWrite(stamp);
117        }
118    }
119
120    public static <R, T extends Throwable> R supplyWithWriteLockT(StampedLock lock, ThrowingSupplier<R, T> task) throws T {
121        long stamp = lock.writeLock();
122
123        try {
124            return task.get();
125        } finally {
126            lock.unlockWrite(stamp);
127        }
128    }
129}