HADOOP-13466. Add an AutoCloseableLock class. (Chen Liang)

Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/331ef251
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/331ef251
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/331ef251

Branch: refs/heads/YARN-2915
Commit: 331ef251527f2cb7f1bfa8e1b745b889e538e8a0
Parents: b8ca84a
Author: Arpit Agarwal <a...@apache.org>
Authored: Thu Aug 4 12:25:39 2016 -0700
Committer: Arpit Agarwal <a...@apache.org>
Committed: Thu Aug 4 12:25:39 2016 -0700

----------------------------------------------------------------------
 .../apache/hadoop/util/AutoCloseableLock.java   | 122 +++++++++++++++++++
 .../hadoop/util/TestAutoCloseableLock.java      |  95 +++++++++++++++
 2 files changed, 217 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/331ef251/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/AutoCloseableLock.java
----------------------------------------------------------------------
diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/AutoCloseableLock.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/AutoCloseableLock.java
new file mode 100644
index 0000000..2aa8578
--- /dev/null
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/AutoCloseableLock.java
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.util;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * This is a wrap class of a ReentrantLock. Extending AutoCloseable
+ * interface such that the users can use a try-with-resource syntax.
+ */
+public class AutoCloseableLock implements AutoCloseable {
+
+  private final ReentrantLock lock;
+
+  /**
+   * Creates an instance of {@code AutoCloseableLock}, initializes
+   * the underlying {@code ReentrantLock} object.
+   */
+  public AutoCloseableLock() {
+    this.lock = new ReentrantLock();
+  }
+
+  /**
+   * A wrapper method that makes a call to {@code lock()} of the underlying
+   * {@code ReentrantLock} object.
+   *
+   * Acquire teh lock it is not held by another thread, then sets
+   * lock held count to one, then returns immediately.
+   *
+   * If the current thread already holds the lock, increase the lock
+   * help count by one and returns immediately.
+   *
+   * If the lock is held by another thread, the current thread is
+   * suspended until the lock has been acquired by current thread.
+   *
+   * @return The {@code ReentrantLock} object itself. This is to
+   * support try-with-resource syntax.
+   */
+  public AutoCloseableLock acquire() {
+    lock.lock();
+    return this;
+  }
+
+  /**
+   * A wrapper method that makes a call to {@code unlock()} of the
+   * underlying {@code ReentrantLock} object.
+   *
+   * Attempts to release the lock.
+   *
+   * If the current thread holds the lock, decrements the hold
+   * count. If the hold count reaches zero, the lock is released.
+   *
+   * If the current thread does not hold the lock, then
+   * {@link IllegalMonitorStateException} is thrown.
+   */
+  public void release() {
+    lock.unlock();
+  }
+
+  /**
+   * Attempts to release the lock by making a call to {@code release()}.
+   *
+   * This is to implement {@code close()} method from {@code AutoCloseable}
+   * interface. This allows users to user a try-with-resource syntax, where
+   * the lock can be automatically released.
+   */
+  @Override
+  public void close() {
+    release();
+  }
+
+  /**
+   * A wrapper method that makes a call to {@code tryLock()} of
+   * the underlying {@code ReentrantLock} object.
+   *
+   * If the lock is not held by another thread, acquires the lock, set the
+   * hold count to one and returns {@code true}.
+   *
+   * If the current thread already holds the lock, the increment the hold
+   * count by one and returns {@code true}.
+   *
+   * If the lock is held by another thread then the method returns
+   * immediately with {@code false}.
+   *
+   * @return {@code true} if the lock was free and was acquired by the
+   *          current thread, or the lock was already held by the current
+   *          thread; and {@code false} otherwise.
+   */
+  public boolean tryLock() {
+    return lock.tryLock();
+  }
+
+  /**
+   * A wrapper method that makes a call to {@code isLocked()} of
+   * the underlying {@code ReentrantLock} object.
+   *
+   * Queries if this lock is held by any thread. This method is
+   * designed for use in monitoring of the system state,
+   * not for synchronization control.
+   *
+   * @return {@code true} if any thread holds this lock and
+   *         {@code false} otherwise
+   */
+  public boolean isLocked() {
+    return lock.isLocked();
+  }
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/331ef251/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestAutoCloseableLock.java
----------------------------------------------------------------------
diff --git 
a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestAutoCloseableLock.java
 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestAutoCloseableLock.java
new file mode 100644
index 0000000..cd5447d
--- /dev/null
+++ 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestAutoCloseableLock.java
@@ -0,0 +1,95 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+/**
+ * A test class for AutoCloseableLock.
+ */
+public class TestAutoCloseableLock {
+
+  /**
+   * Test the basic lock and unlock operation.
+   */
+  @Test
+  public void testLockAcquireRelease() {
+    AutoCloseableLock lock = new AutoCloseableLock();
+    AutoCloseableLock newlock = lock.acquire();
+    // Ensure acquire the same lock object.
+    assertEquals(newlock, lock);
+    // Ensure it locked now.
+    assertTrue(lock.isLocked());
+    lock.release();
+    // Ensure it is unlocked now.
+    assertFalse(lock.isLocked());
+  }
+
+  /**
+   * Test when lock is acquired, no other thread can
+   * lock it.
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testMultipleThread() throws Exception {
+    AutoCloseableLock lock = new AutoCloseableLock();
+    lock.acquire();
+    assertTrue(lock.isLocked());
+    Thread competingThread = new Thread() {
+      @Override
+      public void run() {
+        assertTrue(lock.isLocked());
+        assertFalse(lock.tryLock());
+      }
+    };
+    competingThread.start();
+    competingThread.join();
+    assertTrue(lock.isLocked());
+    lock.release();
+    assertFalse(lock.isLocked());
+  }
+
+  /**
+   * Test the correctness under try-with-resource syntax.
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testTryWithResourceSyntax() throws Exception {
+    AutoCloseableLock lock = new AutoCloseableLock();
+    try(AutoCloseableLock localLock = lock.acquire()) {
+      assertEquals(localLock, lock);
+      assertTrue(lock.isLocked());
+      Thread competingThread = new Thread() {
+        @Override
+        public void run() {
+          assertTrue(lock.isLocked());
+          assertFalse(lock.tryLock());
+        }
+      };
+      competingThread.start();
+      competingThread.join();
+      assertTrue(localLock.isLocked());
+    }
+    assertFalse(lock.isLocked());
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to