Mercurial Hosting > nabble
comparison src/fschmidt/util/locks/TimedReadWriteLocker.java @ 68:00520880ad02
add fschmidt source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 05 Oct 2025 17:24:15 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:9d0fefce6985 | 68:00520880ad02 |
---|---|
1 /* | |
2 Copyright (c) 2008 Franklin Schmidt <fschmidt@gmail.com> | |
3 | |
4 Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 of this software and associated documentation files (the "Software"), to deal | |
6 in the Software without restriction, including without limitation the rights | |
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 copies of the Software, and to permit persons to whom the Software is | |
9 furnished to do so, subject to the following conditions: | |
10 | |
11 The above copyright notice and this permission notice shall be included in | |
12 all copies or substantial portions of the Software. | |
13 | |
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
20 THE SOFTWARE. | |
21 */ | |
22 | |
23 package fschmidt.util.locks; | |
24 | |
25 import java.util.Map; | |
26 import java.util.HashMap; | |
27 import java.util.concurrent.TimeUnit; | |
28 import java.util.concurrent.locks.Lock; | |
29 import java.util.concurrent.locks.ReadWriteLock; | |
30 import java.util.concurrent.locks.ReentrantReadWriteLock; | |
31 | |
32 | |
33 public final class TimedReadWriteLocker<T> implements ReadWriteLocker<T> { | |
34 | |
35 private static class Tracker { | |
36 final ReentrantReadWriteLock lock0 = new ReentrantReadWriteLock(); | |
37 final ReadWriteLock lock = new TimedReadWriteLock(lock0); | |
38 int waiters = 0; | |
39 } | |
40 | |
41 private final Map<T,Tracker> map = new HashMap<T,Tracker>(); | |
42 | |
43 private Tracker getTracker(T obj) { | |
44 Tracker t = map.get(obj); | |
45 if( t==null ) { | |
46 t = new Tracker(); | |
47 map.put(obj,t); | |
48 } | |
49 return t; | |
50 } | |
51 | |
52 private Tracker getTrackerForWait(T obj) { | |
53 synchronized(map) { | |
54 Tracker t = getTracker(obj); | |
55 t.waiters++; | |
56 return t; | |
57 } | |
58 } | |
59 | |
60 private void afterWait(Tracker t) { | |
61 synchronized(map) { | |
62 t.waiters--; | |
63 } | |
64 } | |
65 | |
66 private void maybeRemove(T obj,Tracker t) { | |
67 if( t.waiters==0 && !t.lock0.isWriteLocked() && t.lock0.getReadLockCount()==0 ) { | |
68 map.remove(obj); | |
69 } | |
70 } | |
71 | |
72 private final Locker<T> writeLocker = new Locker<T>() { | |
73 | |
74 public void lock(T obj) { | |
75 Tracker t = getTrackerForWait(obj); | |
76 try { | |
77 t.lock.writeLock().lock(); | |
78 } finally { | |
79 afterWait(t); | |
80 } | |
81 } | |
82 | |
83 public boolean tryLock(T obj) { | |
84 synchronized(map) { | |
85 return getTracker(obj).lock.writeLock().tryLock(); | |
86 } | |
87 } | |
88 | |
89 public boolean tryLock(T obj,long time,TimeUnit unit) | |
90 throws InterruptedException | |
91 { | |
92 Tracker t = getTrackerForWait(obj); | |
93 try { | |
94 return t.lock.writeLock().tryLock(time,unit); | |
95 } finally { | |
96 afterWait(t); | |
97 } | |
98 } | |
99 | |
100 public void unlock(T obj) { | |
101 synchronized(map) { | |
102 Tracker t = map.get(obj); | |
103 t.lock.writeLock().unlock(); | |
104 maybeRemove(obj,t); | |
105 } | |
106 } | |
107 }; | |
108 | |
109 private final Locker<T> readLocker = new Locker<T>() { | |
110 | |
111 public void lock(T obj) { | |
112 Tracker t = getTrackerForWait(obj); | |
113 try { | |
114 t.lock.readLock().lock(); | |
115 } finally { | |
116 afterWait(t); | |
117 } | |
118 } | |
119 | |
120 public boolean tryLock(T obj) { | |
121 synchronized(map) { | |
122 return getTracker(obj).lock.readLock().tryLock(); | |
123 } | |
124 } | |
125 | |
126 public boolean tryLock(T obj,long time,TimeUnit unit) | |
127 throws InterruptedException | |
128 { | |
129 Tracker t = getTrackerForWait(obj); | |
130 try { | |
131 return t.lock.readLock().tryLock(time,unit); | |
132 } finally { | |
133 afterWait(t); | |
134 } | |
135 } | |
136 | |
137 public void unlock(T obj) { | |
138 synchronized(map) { | |
139 Tracker t = map.get(obj); | |
140 t.lock.readLock().unlock(); | |
141 maybeRemove(obj,t); | |
142 } | |
143 } | |
144 }; | |
145 | |
146 public Locker<T> readLocker() { | |
147 return readLocker; | |
148 } | |
149 | |
150 public Locker<T> writeLocker() { | |
151 return writeLocker; | |
152 } | |
153 | |
154 } |