This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new ed0f5be  Reimplement such that locking and unlocking take place in the 
same method.
ed0f5be is described below

commit ed0f5bea111c449fa17478d7e0c7c37c3ede3863
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Thu Jun 18 12:48:46 2020 -0400

    Reimplement such that locking and unlocking take place in the same
    method.
---
 .../org/apache/commons/lang3/concurrent/Locks.java | 61 ++++++++++++----------
 1 file changed, 32 insertions(+), 29 deletions(-)

diff --git a/src/main/java/org/apache/commons/lang3/concurrent/Locks.java 
b/src/main/java/org/apache/commons/lang3/concurrent/Locks.java
index f78a9dd..f8ecae9 100644
--- a/src/main/java/org/apache/commons/lang3/concurrent/Locks.java
+++ b/src/main/java/org/apache/commons/lang3/concurrent/Locks.java
@@ -18,36 +18,36 @@ package org.apache.commons.lang3.concurrent;
 
 import java.util.Objects;
 import java.util.concurrent.locks.StampedLock;
+import java.util.function.LongSupplier;
 
 import org.apache.commons.lang3.function.Failable;
 import org.apache.commons.lang3.function.FailableConsumer;
 import org.apache.commons.lang3.function.FailableFunction;
 
-
 /**
  * Utility class for working with {@link java.util.concurrent.locks.Lock 
locked objects}. Locked objects are an
  * alternative to synchronization.
  *
- * Locking is preferable, if there is a distinction between read access 
(multiple threads may have read
- * access concurrently), and write access (only one thread may have write 
access at any given time.
- * In comparison, synchronization doesn't support read access, because 
synchronized access is exclusive.
+ * Locking is preferable, if there is a distinction between read access 
(multiple threads may have read access
+ * concurrently), and write access (only one thread may have write access at 
any given time. In comparison,
+ * synchronization doesn't support read access, because synchronized access is 
exclusive.
  *
  * Using this class is fairly straightforward:
  * <ol>
- *   <li>While still in single thread mode, create an instance of {@link 
Locks.Lock} by calling
- *     {@link #lock(Object)}, passing the object, which needs to be locked. 
Discard all
- *     references to the locked object. Instead, use references to the 
lock.</li>
- *   <li>If you want to access the locked object, create a {@link 
FailableConsumer}. The consumer
- *     will receive the locked object as a parameter. For convenience, the 
consumer may be
- *     implemented as a Lambda. Then invoke {@link 
Locks.Lock#runReadLocked(FailableConsumer)},
- *     or {@link Locks.Lock#runWriteLocked(FailableConsumer)}, passing the 
consumer.</li>
- *   <li>As an alternative, if you need to produce a result object, you may 
use a
- *     {@link FailableFunction}. This function may also be implemented as a 
Lambda. To
- *     have the function executed, invoke {@link 
Locks.Lock#callReadLocked(FailableFunction)}, or
- *     {@link Locks.Lock#callWriteLocked(FailableFunction)}.</li>
+ * <li>While still in single thread mode, create an instance of {@link 
Locks.Lock} by calling {@link #lock(Object)},
+ * passing the object, which needs to be locked. Discard all references to the 
locked object. Instead, use references to
+ * the lock.</li>
+ * <li>If you want to access the locked object, create a {@link 
FailableConsumer}. The consumer will receive the locked
+ * object as a parameter. For convenience, the consumer may be implemented as 
a Lambda. Then invoke
+ * {@link Locks.Lock#runReadLocked(FailableConsumer)}, or {@link 
Locks.Lock#runWriteLocked(FailableConsumer)}, passing
+ * the consumer.</li>
+ * <li>As an alternative, if you need to produce a result object, you may use 
a {@link FailableFunction}. This function
+ * may also be implemented as a Lambda. To have the function executed, invoke
+ * {@link Locks.Lock#callReadLocked(FailableFunction)}, or {@link 
Locks.Lock#callWriteLocked(FailableFunction)}.</li>
  * </ol>
  *
  * Example: A thread safe logger class.
+ *
  * <pre>
  *   public class SimpleLogger {
  *     private final Lock&lt;PrintStream&gt; lock;
@@ -65,6 +65,7 @@ import org.apache.commons.lang3.function.FailableFunction;
  *         lock.runWriteLocked((ps) -&gt; { ps.write(buffer); ps.println(); });
  *     }
  * </pre>
+ *
  * @since 3.11
  */
 public class Locks {
@@ -73,40 +74,42 @@ public class Locks {
         private final O lockedObject;
         private final StampedLock lock = new StampedLock();
 
-        public Lock(O lockedObject) {
+        public Lock(final O lockedObject) {
             this.lockedObject = Objects.requireNonNull(lockedObject, "Locked 
Object");
         }
 
-        public void runReadLocked(FailableConsumer<O, ?> consumer) {
-            acceptLocked(lock.readLock(), consumer);
+        public void runReadLocked(final FailableConsumer<O, ?> consumer) {
+            acceptLocked(() -> lock.readLock(), consumer);
         }
 
-        public void runWriteLocked(FailableConsumer<O, ?> consumer) {
-            acceptLocked(lock.writeLock(), consumer);
+        public void runWriteLocked(final FailableConsumer<O, ?> consumer) {
+            acceptLocked(() -> lock.writeLock(), consumer);
         }
 
-        public <T> T callReadLocked(FailableFunction<O, T, ?> function) {
-            return applyLocked(lock.readLock(), function);
+        public <T> T callReadLocked(final FailableFunction<O, T, ?> function) {
+            return applyLocked(() -> lock.readLock(), function);
         }
 
-        public <T> T callWriteLocked(FailableFunction<O, T, ?> function) {
-            return applyLocked(lock.writeLock(), function);
+        public <T> T callWriteLocked(final FailableFunction<O, T, ?> function) 
{
+            return applyLocked(() -> lock.writeLock(), function);
         }
 
-        protected void acceptLocked(long stamp, FailableConsumer<O, ?> 
consumer) {
+        protected void acceptLocked(final LongSupplier stampSupplier, final 
FailableConsumer<O, ?> consumer) {
+            final long stamp = stampSupplier.getAsLong();
             try {
                 consumer.accept(lockedObject);
-            } catch (Throwable t) {
+            } catch (final Throwable t) {
                 throw Failable.rethrow(t);
             } finally {
                 lock.unlock(stamp);
             }
         }
 
-        protected <T> T applyLocked(long stamp, FailableFunction<O, T, ?> 
function) {
+        protected <T> T applyLocked(final LongSupplier stampSupplier, final 
FailableFunction<O, T, ?> function) {
+            final long stamp = stampSupplier.getAsLong();
             try {
                 return function.apply(lockedObject);
-            } catch (Throwable t) {
+            } catch (final Throwable t) {
                 throw Failable.rethrow(t);
             } finally {
                 lock.unlock(stamp);
@@ -114,7 +117,7 @@ public class Locks {
         }
     }
 
-    public static <O extends Object> Locks.Lock<O> lock(O object) {
+    public static <O extends Object> Locks.Lock<O> lock(final O object) {
         return new Locks.Lock<>(object);
     }
 }

Reply via email to