1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.configuration2.sync; 18 19 import java.util.concurrent.locks.ReadWriteLock; 20 import java.util.concurrent.locks.ReentrantReadWriteLock; 21 22 /** 23 * <p> 24 * A special implementation of {@code Synchronizer} based on the JDK's {@code ReentrantReadWriteLock} class. 25 * </p> 26 * <p> 27 * This class manages a {@code ReadWriteLock} object internally. The methods of the {@code Synchronizer} interface are 28 * delegated to this lock. So this class behaves in the same way as documented for {@code ReentrantReadWriteLock}. 29 * </p> 30 * <p> 31 * Using this {@code Synchronizer} implementation is appropriate to make configuration objects thread-safe. This means 32 * that multiple threads can read configuration data in parallel; if one thread wants to update the configuration, this 33 * happens with an exclusive lock. 34 * </p> 35 * 36 * @since 2.0 37 */ 38 public class ReadWriteSynchronizer implements Synchronizer { 39 /** The lock object used by this Synchronizer. */ 40 private final ReadWriteLock lock; 41 42 /** 43 * Creates a new instance of {@code ReadWriteSynchronizer} and initializes it with the given lock object. This 44 * constructor can be used to pass a lock object which has been configured externally. If the lock object is 45 * <b>null</b>, a default lock object is created. 46 * 47 * @param l the lock object to be used (can be <b>null</b>) 48 */ 49 public ReadWriteSynchronizer(final ReadWriteLock l) { 50 lock = l != null ? l : createDefaultLock(); 51 } 52 53 /** 54 * Creates a new instance of {@code ReadWriteSynchronizer} and initializes it with a lock object of type 55 * {@code ReentrantReadWriteLock}. 56 */ 57 public ReadWriteSynchronizer() { 58 this(null); 59 } 60 61 @Override 62 public void beginRead() { 63 lock.readLock().lock(); 64 } 65 66 @Override 67 public void endRead() { 68 lock.readLock().unlock(); 69 } 70 71 @Override 72 public void beginWrite() { 73 lock.writeLock().lock(); 74 } 75 76 @Override 77 public void endWrite() { 78 lock.writeLock().unlock(); 79 } 80 81 /** 82 * Returns a new default lock object which is used if no lock is passed to the constructor. 83 * 84 * @return the new default lock object 85 */ 86 private static ReadWriteLock createDefaultLock() { 87 return new ReentrantReadWriteLock(); 88 } 89 }