11package edu .coursera .concurrent ;
22
3+ import java .util .concurrent .locks .ReentrantLock ;
4+ import java .util .concurrent .locks .ReentrantReadWriteLock ;
5+
36/**
47 * Wrapper class for two lock-based concurrent list implementations.
58 */
@@ -26,6 +29,9 @@ public static final class CoarseList extends ListSet {
2629 public CoarseList () {
2730 super ();
2831 }
32+
33+ // Invoke a lock that is used in all thread-safe methods
34+ private final ReentrantLock lock = new ReentrantLock ();
2935
3036 /**
3137 * {@inheritDoc}
@@ -34,22 +40,28 @@ public CoarseList() {
3440 */
3541 @ Override
3642 boolean add (final Integer object ) {
37- Entry pred = this .head ;
38- Entry curr = pred .next ;
39-
40- while (curr .object .compareTo (object ) < 0 ) {
41- pred = curr ;
42- curr = curr .next ;
43- }
44-
45- if (object .equals (curr .object )) {
46- return false ;
47- } else {
48- final Entry entry = new Entry (object );
49- entry .next = curr ;
50- pred .next = entry ;
51- return true ;
52- }
43+ try {
44+ lock .lock ();
45+
46+ Entry pred = this .head ;
47+ Entry curr = pred .next ;
48+
49+ while (curr .object .compareTo (object ) < 0 ) {
50+ pred = curr ;
51+ curr = curr .next ;
52+ }
53+
54+ if (object .equals (curr .object )) {
55+ return false ;
56+ } else {
57+ final Entry entry = new Entry (object );
58+ entry .next = curr ;
59+ pred .next = entry ;
60+ return true ;
61+ }
62+ } finally {
63+ lock .unlock ();
64+ }
5365 }
5466
5567 /**
@@ -59,20 +71,26 @@ boolean add(final Integer object) {
5971 */
6072 @ Override
6173 boolean remove (final Integer object ) {
62- Entry pred = this .head ;
63- Entry curr = pred .next ;
64-
65- while (curr .object .compareTo (object ) < 0 ) {
66- pred = curr ;
67- curr = curr .next ;
68- }
69-
70- if (object .equals (curr .object )) {
71- pred .next = curr .next ;
72- return true ;
73- } else {
74- return false ;
75- }
74+ try {
75+ lock .lock ();
76+
77+ Entry pred = this .head ;
78+ Entry curr = pred .next ;
79+
80+ while (curr .object .compareTo (object ) < 0 ) {
81+ pred = curr ;
82+ curr = curr .next ;
83+ }
84+
85+ if (object .equals (curr .object )) {
86+ pred .next = curr .next ;
87+ return true ;
88+ } else {
89+ return false ;
90+ }
91+ } finally {
92+ lock .unlock ();
93+ }
7694 }
7795
7896 /**
@@ -82,6 +100,9 @@ boolean remove(final Integer object) {
82100 */
83101 @ Override
84102 boolean contains (final Integer object ) {
103+ try {
104+ lock .lock ();
105+
85106 Entry pred = this .head ;
86107 Entry curr = pred .next ;
87108
@@ -90,6 +111,10 @@ boolean contains(final Integer object) {
90111 curr = curr .next ;
91112 }
92113 return object .equals (curr .object );
114+
115+ } finally {
116+ lock .unlock ();
117+ }
93118 }
94119 }
95120
@@ -116,6 +141,9 @@ public static final class RWCoarseList extends ListSet {
116141 public RWCoarseList () {
117142 super ();
118143 }
144+
145+ // Instantiate ReadWriteLock that is used in all thread-safe methods
146+ private final ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock ();
119147
120148 /**
121149 * {@inheritDoc}
@@ -124,22 +152,28 @@ public RWCoarseList() {
124152 */
125153 @ Override
126154 boolean add (final Integer object ) {
127- Entry pred = this .head ;
128- Entry curr = pred .next ;
129-
130- while (curr .object .compareTo (object ) < 0 ) {
131- pred = curr ;
132- curr = curr .next ;
133- }
134-
135- if (object .equals (curr .object )) {
136- return false ;
137- } else {
138- final Entry entry = new Entry (object );
139- entry .next = curr ;
140- pred .next = entry ;
141- return true ;
142- }
155+ try {
156+ rwlock .writeLock ().lock ();
157+
158+ Entry pred = this .head ;
159+ Entry curr = pred .next ;
160+
161+ while (curr .object .compareTo (object ) < 0 ) {
162+ pred = curr ;
163+ curr = curr .next ;
164+ }
165+
166+ if (object .equals (curr .object )) {
167+ return false ;
168+ } else {
169+ final Entry entry = new Entry (object );
170+ entry .next = curr ;
171+ pred .next = entry ;
172+ return true ;
173+ }
174+ } finally {
175+ rwlock .writeLock ().unlock ();
176+ }
143177 }
144178
145179 /**
@@ -149,20 +183,26 @@ boolean add(final Integer object) {
149183 */
150184 @ Override
151185 boolean remove (final Integer object ) {
152- Entry pred = this .head ;
153- Entry curr = pred .next ;
154-
155- while (curr .object .compareTo (object ) < 0 ) {
156- pred = curr ;
157- curr = curr .next ;
158- }
159-
160- if (object .equals (curr .object )) {
161- pred .next = curr .next ;
162- return true ;
163- } else {
164- return false ;
165- }
186+ try {
187+ rwlock .writeLock ().lock ();
188+
189+ Entry pred = this .head ;
190+ Entry curr = pred .next ;
191+
192+ while (curr .object .compareTo (object ) < 0 ) {
193+ pred = curr ;
194+ curr = curr .next ;
195+ }
196+
197+ if (object .equals (curr .object )) {
198+ pred .next = curr .next ;
199+ return true ;
200+ } else {
201+ return false ;
202+ }
203+ } finally {
204+ rwlock .writeLock ().unlock ();
205+ }
166206 }
167207
168208 /**
@@ -172,14 +212,20 @@ boolean remove(final Integer object) {
172212 */
173213 @ Override
174214 boolean contains (final Integer object ) {
175- Entry pred = this .head ;
176- Entry curr = pred .next ;
177-
178- while (curr .object .compareTo (object ) < 0 ) {
179- pred = curr ;
180- curr = curr .next ;
181- }
182- return object .equals (curr .object );
215+ try {
216+ rwlock .readLock ().lock ();
217+
218+ Entry pred = this .head ;
219+ Entry curr = pred .next ;
220+
221+ while (curr .object .compareTo (object ) < 0 ) {
222+ pred = curr ;
223+ curr = curr .next ;
224+ }
225+ return object .equals (curr .object );
226+ } finally {
227+ rwlock .readLock ().unlock ();
228+ }
183229 }
184230 }
185231}
0 commit comments