1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /** 5 ******************************************************************************* 6 * Copyright (C) 2001-2013, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 package ohos.global.icu.impl; 11 12 import java.util.concurrent.locks.ReentrantReadWriteLock; 13 14 15 /** 16 * <p>A Reader/Writer lock originally written for ICU service 17 * implementation. The internal implementation was replaced 18 * with the JDK's stock read write lock (ReentrantReadWriteLock) 19 * for ICU 52.</p> 20 * 21 * <p>This assumes that there will be little writing contention. 22 * It also doesn't allow active readers to acquire and release 23 * a write lock, or deal with priority inversion issues.</p> 24 * 25 * <p>Access to the lock should be enclosed in a try/finally block 26 * in order to ensure that the lock is always released in case of 27 * exceptions:<br><pre> 28 * try { 29 * lock.acquireRead(); 30 * // use service protected by the lock 31 * } 32 * finally { 33 * lock.releaseRead(); 34 * } 35 * </pre></p> 36 * 37 * <p>The lock provides utility methods getStats and clearStats 38 * to return statistics on the use of the lock.</p> 39 * @hide exposed on OHOS 40 */ 41 public class ICURWLock { 42 private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 43 44 private Stats stats = null; 45 46 /** 47 * Internal class used to gather statistics on the RWLock. 48 * @hide exposed on OHOS 49 */ 50 public final static class Stats { 51 /** 52 * Number of times read access granted (read count). 53 */ 54 public int _rc; 55 56 /** 57 * Number of times concurrent read access granted (multiple read count). 58 */ 59 public int _mrc; 60 61 /** 62 * Number of times blocked for read (waiting reader count). 63 */ 64 public int _wrc; // wait for read 65 66 /** 67 * Number of times write access granted (writer count). 68 */ 69 public int _wc; 70 71 /** 72 * Number of times blocked for write (waiting writer count). 73 */ 74 public int _wwc; 75 Stats()76 private Stats() { 77 } 78 Stats(int rc, int mrc, int wrc, int wc, int wwc)79 private Stats(int rc, int mrc, int wrc, int wc, int wwc) { 80 this._rc = rc; 81 this._mrc = mrc; 82 this._wrc = wrc; 83 this._wc = wc; 84 this._wwc = wwc; 85 } 86 Stats(Stats rhs)87 private Stats(Stats rhs) { 88 this(rhs._rc, rhs._mrc, rhs._wrc, rhs._wc, rhs._wwc); 89 } 90 91 /** 92 * Return a string listing all the stats. 93 */ 94 @Override toString()95 public String toString() { 96 return " rc: " + _rc + 97 " mrc: " + _mrc + 98 " wrc: " + _wrc + 99 " wc: " + _wc + 100 " wwc: " + _wwc; 101 } 102 } 103 104 /** 105 * Reset the stats. Returns existing stats, if any. 106 */ resetStats()107 public synchronized Stats resetStats() { 108 Stats result = stats; 109 stats = new Stats(); 110 return result; 111 } 112 113 /** 114 * Clear the stats (stop collecting stats). Returns existing stats, if any. 115 */ clearStats()116 public synchronized Stats clearStats() { 117 Stats result = stats; 118 stats = null; 119 return result; 120 } 121 122 /** 123 * Return a snapshot of the current stats. This does not reset the stats. 124 */ getStats()125 public synchronized Stats getStats() { 126 return stats == null ? null : new Stats(stats); 127 } 128 129 /** 130 * <p>Acquire a read lock, blocking until a read lock is 131 * available. Multiple readers can concurrently hold the read 132 * lock.</p> 133 * 134 * <p>If there's a writer, or a waiting writer, increment the 135 * waiting reader count and block on this. Otherwise 136 * increment the active reader count and return. Caller must call 137 * releaseRead when done (for example, in a finally block).</p> 138 */ acquireRead()139 public void acquireRead() { 140 if (stats != null) { // stats is null by default 141 synchronized (this) { 142 stats._rc++; 143 if (rwl.getReadLockCount() > 0) { 144 stats._mrc++; 145 } 146 if (rwl.isWriteLocked()) { 147 stats._wrc++; 148 } 149 } 150 } 151 rwl.readLock().lock(); 152 } 153 154 /** 155 * <p>Release a read lock and return. An error will be thrown 156 * if a read lock is not currently held.</p> 157 * 158 * <p>If this is the last active reader, notify the oldest 159 * waiting writer. Call when finished with work 160 * controlled by acquireRead.</p> 161 */ releaseRead()162 public void releaseRead() { 163 rwl.readLock().unlock(); 164 } 165 166 /** 167 * <p>Acquire the write lock, blocking until the write lock is 168 * available. Only one writer can acquire the write lock, and 169 * when held, no readers can acquire the read lock.</p> 170 * 171 * <p>If there are no readers and no waiting writers, mark as 172 * having an active writer and return. Otherwise, add a lock to the 173 * end of the waiting writer list, and block on it. Caller 174 * must call releaseWrite when done (for example, in a finally 175 * block).<p> 176 */ acquireWrite()177 public void acquireWrite() { 178 if (stats != null) { // stats is null by default 179 synchronized (this) { 180 stats._wc++; 181 if (rwl.getReadLockCount() > 0 || rwl.isWriteLocked()) { 182 stats._wwc++; 183 } 184 } 185 } 186 rwl.writeLock().lock(); 187 } 188 189 /** 190 * <p>Release the write lock and return. An error will be thrown 191 * if the write lock is not currently held.</p> 192 * 193 * <p>If there are waiting readers, make them all active and 194 * notify all of them. Otherwise, notify the oldest waiting 195 * writer, if any. Call when finished with work controlled by 196 * acquireWrite.</p> 197 */ releaseWrite()198 public void releaseWrite() { 199 rwl.writeLock().unlock(); 200 } 201 } 202