-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReadWriteLock.java
executable file
·156 lines (141 loc) · 4.35 KB
/
ReadWriteLock.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import java.util.concurrent.Semaphore;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Date;
// Handles reader-writer problem that arises when
// managing shared resources.
// Orders queued threads based on Lamport clock of
// their Job.
// Allows for simultaneous read operations to occur
// until a write is required which locks the resource
// to all other operations until it is finished
abstract class ReadWriteLock <T,C>{
private Semaphore queueLock;
private Semaphore readerCountAccess;
private Semaphore resourceAccess;
private int readerCount;
public ReadWriteLock(){
resourceAccess = new Semaphore(1, true);
readerCountAccess = new Semaphore(1);
queueLock = new Semaphore(1, true);
readerCount = 0;
}
// Thread safe method to read the shared resource
public T read() throws InterruptedException {
T read = null;
queueLock.acquire();
// Increment reader count
readerCountAccess.acquire();
readerCount++;
// First reader takes control of resource
if (readerCount == 1){ resourceAccess.acquire(); }
// Dequeues next thread in line
queueLock.release();
readerCountAccess.release();
// Critical Section
read = doRead();
// Critical Section
// Decrement reader count
readerCountAccess.acquire();
readerCount--;
// Last reader releases the resource
if (readerCount == 0){ resourceAccess.release(); }
readerCountAccess.release();
return read;
}
// Thread safe method to write to the shared resource
public void write(C newData, String key, Boolean delete)
throws InterruptedException {
queueLock.acquire();
// No additional threads dequeue until writer
// has control of the resource
resourceAccess.acquire();
queueLock.release();
// Critical Section
doWrite(newData, key, delete);
// Critical Section
resourceAccess.release();
}
// Implemented in derived class
abstract T doRead();
abstract void doWrite(C newData, String key,
Boolean delete);
}
// Implementation of Reader-Writer lock for client records
class TimesMapLock extends ReadWriteLock <HashMap<String,Times>,Times>{
private HashMap<String,Times> mTimesMap;
public TimesMapLock(){
super();
mTimesMap = new HashMap<String,Times>();
}
// Class specific access or modify methods
@Override
public HashMap<String,Times> doRead(){
HashMap<String,Times> copy;
copy = new HashMap<String,Times>();
// Creates a copy of the hash-map
for (String key : mTimesMap.keySet()){
Times time = new Times();
time.copy(mTimesMap.get(key));
copy.put(key, time);
}
return copy;
}
@Override
public void doWrite(Times newData,
String key, Boolean delete) {
if (delete) { mTimesMap.remove(key); }
else { mTimesMap.put(key, newData); }
}
}
// Implementation of Reader-Writer lock for client content
class ContentMapLock extends ReadWriteLock <HashMap<String,Content>,Content>{
private HashMap<String,Content> mContentMap;
public ContentMapLock(){
super();
mContentMap = new HashMap<String,Content>();
}
@Override
public void doWrite(Content newData,
String key, Boolean delete) {
if (delete) { mContentMap.remove(key); }
else { mContentMap.put(key, newData); }
}
@Override
public HashMap<String,Content> doRead() {
HashMap<String,Content> copy;
copy = new HashMap<String,Content>();
// Creates a copy of the hash-map
for (String key: mContentMap.keySet()){
Content content = new Content();
content.copy(mContentMap.get(key));
copy.put(key, content);
}
return copy;
}
}
// Implementation of Reader-Writer lock for the aggregated ATOMFeed
class FeedLock extends ReadWriteLock <ATOMFeed, ArrayList<Content>>{
private ATOMFeed mFeed;
public FeedLock(String filename){
super();
mFeed = initFeed(filename);
}
@Override
public void doWrite(ArrayList<Content> newData,
String key, Boolean delete)
{ mFeed.setEntries(newData); }
@Override
public ATOMFeed doRead(){
ATOMFeed copy = new ATOMFeed();
copy.copy(mFeed);
return copy;
}
// Adds informational fields to the servers feed
private ATOMFeed initFeed(String filename){
ATOMFeed feed;
try{ feed = Translator.feedFileToObject(filename); }
catch (Exception e) { e.printStackTrace(); feed = null; }
return feed;
}
}