Skip to content

Commit 770b55a

Browse files
author
Dmytro Voronkevych
committed
Improved code readability
1 parent 2bcc3cb commit 770b55a

File tree

3 files changed

+47
-58
lines changed

3 files changed

+47
-58
lines changed

src/androidTest/java/com/badoo/mobile/util/WeakHandlerChainedRefTest.java

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ public class WeakHandlerChainedRefTest {
2828
private Runnable mSecondRunnable;
2929
private Lock mLock;
3030
private WeakHandler.ChainedRef mRefHead;
31-
private WeakHandler.ChainedRef mFirst;
3231
private WeakHandler.ChainedRef mSecond;
32+
private WeakHandler.ChainedRef mFirst;
3333
private WeakHandler.WeakRunnable mHeadWeakRunnable;
3434
private WeakHandler.WeakRunnable mFirstWeakRunnable;
3535
private WeakHandler.WeakRunnable mSecondWeakRunnable;
3636

37+
// Creates linked list refHead <-> first <-> second
3738
@Before
3839
public void setUp() {
3940
mLock = new ReentrantLock();
@@ -51,80 +52,83 @@ public String toString() {
5152
mFirst = new WeakHandler.ChainedRef(mLock, mFirstRunnable) {
5253
@Override
5354
public String toString() {
54-
return "first";
55+
return "second";
5556
}
5657
};
5758
mSecond = new WeakHandler.ChainedRef(mLock, mSecondRunnable) {
5859
@Override
5960
public String toString() {
60-
return "second";
61+
return "first";
6162
}
6263
};
6364

64-
mRefHead.insertAbove(mFirst);
65-
mRefHead.insertAbove(mSecond);
65+
mRefHead.insertAfter(mSecond);
66+
mRefHead.insertAfter(mFirst);
6667

6768
mHeadWeakRunnable = mRefHead.wrapper;
6869
mFirstWeakRunnable = mFirst.wrapper;
6970
mSecondWeakRunnable = mSecond.wrapper;
7071
}
7172

7273
@Test
73-
public void insertAbove() {
74-
assertSame(mSecond, mRefHead.next);
75-
assertSame(mFirst, mRefHead.next.next);
74+
public void insertAfter() {
75+
assertSame(mFirst, mRefHead.next);
76+
assertSame(mSecond, mRefHead.next.next);
7677
assertNull(mRefHead.next.next.next);
7778

7879
assertNull(mRefHead.prev);
79-
assertSame(mSecond, mFirst.prev);
80-
assertSame(mRefHead, mSecond.prev);
80+
assertSame(mFirst, mSecond.prev);
81+
assertSame(mRefHead, mFirst.prev);
8182
}
8283

8384
@Test
8485
public void removeFirst() {
8586
mFirst.remove();
87+
8688
assertNull(mFirst.next);
8789
assertNull(mFirst.prev);
8890

8991
assertSame(mSecond, mRefHead.next);
90-
assertSame(mRefHead, mSecond.prev);
9192
assertNull(mSecond.next);
93+
assertSame(mRefHead, mSecond.prev);
9294
}
9395

9496
@Test
9597
public void removeSecond() {
9698
mSecond.remove();
97-
9899
assertNull(mSecond.next);
99100
assertNull(mSecond.prev);
100101

101102
assertSame(mFirst, mRefHead.next);
102-
assertNull(mFirst.next);
103103
assertSame(mRefHead, mFirst.prev);
104+
assertNull(mFirst.next);
104105
}
105106

106107
@Test
107108
public void removeFirstByRunnable() {
108109
assertSame(mFirstWeakRunnable, mRefHead.remove(mFirstRunnable));
109110
assertSame(mRefHead.next, mSecond);
110111
assertSame(mRefHead, mSecond.prev);
111-
assertNull(mSecond.next);
112+
assertNull(mFirst.next);
113+
assertNull(mFirst.prev);
112114
}
113115

114116
@Test
115117
public void removeSecondByRunnable() {
116118
assertSame(mSecondWeakRunnable, mRefHead.remove(mSecondRunnable));
117119
assertSame(mFirst, mRefHead.next);
118120
assertSame(mRefHead, mFirst.prev);
121+
assertNull(mSecond.next);
122+
assertNull(mSecond.prev);
119123
}
120124

121125
@Test
122-
public void removeUnexistentRunnableReturnNull() {
126+
public void removeNonExistentRunnableReturnNull() {
123127
assertNull(mRefHead.remove(new DummyRunnable()));
124-
assertSame(mSecond, mRefHead.next);
125-
assertNull(mFirst.next);
126-
assertSame(mSecond, mFirst.prev);
127-
assertSame(mRefHead, mSecond.prev);
128+
assertSame(mFirst, mRefHead.next);
129+
assertNull(mSecond.next);
130+
assertSame(mFirst, mSecond.prev);
131+
assertSame(mRefHead, mFirst.prev);
128132
}
129133

130134
private class DummyRunnable implements Runnable {

src/androidTest/java/com/badoo/mobile/util/WeakHandlerTest.java

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import android.os.HandlerThread;
2424
import android.os.SystemClock;
2525
import android.support.test.runner.AndroidJUnit4;
26+
import android.test.FlakyTest;
2627
import android.test.suitebuilder.annotation.MediumTest;
2728

2829
import com.badoo.mobile.util.WeakHandler.ChainedRef;
@@ -32,7 +33,7 @@
3233
import org.junit.Test;
3334
import org.junit.runner.RunWith;
3435

35-
import java.lang.reflect.Field;
36+
import java.util.Collections;
3637
import java.util.HashSet;
3738
import java.util.Set;
3839
import java.util.concurrent.CountDownLatch;
@@ -70,6 +71,7 @@ public void tearDown() {
7071
mHandler.getLooper().quit();
7172
}
7273

74+
@FlakyTest
7375
@Test
7476
public void postDelayed() throws InterruptedException {
7577
final CountDownLatch latch = new CountDownLatch(1);
@@ -88,7 +90,7 @@ public void run() {
8890
assertTrue(executed.get());
8991

9092
long elapsedTime = SystemClock.elapsedRealtime() - startTime;
91-
assertTrue("Elapsed time should be 300, but was " + elapsedTime, elapsedTime <= 305 && elapsedTime >= 300);
93+
assertTrue("Elapsed time should be 300, but was " + elapsedTime, elapsedTime <= 330 && elapsedTime >= 300);
9294
}
9395

9496
@Test
@@ -146,7 +148,7 @@ public void uncaughtException(Thread thread, Throwable ex) {
146148
// Before I fixed impl of WeakHandler it always caused exceptions
147149
}
148150
if (mExceptionInThread.get() != null) {
149-
throw mExceptionInThread.get(); // Exceptiin from HandlerThread. Sometimes it occured as well
151+
throw mExceptionInThread.get(); // Exception from HandlerThread. Sometimes it occured as well
150152
}
151153
thread.getLooper().quit();
152154
}
@@ -155,40 +157,27 @@ public void uncaughtException(Thread thread, Throwable ex) {
155157
@Test(timeout = 30000)
156158
public void concurrentAdd() throws NoSuchFieldException, IllegalAccessException, InterruptedException {
157159
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 50, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(100));
158-
final Set<Runnable> added = new HashSet<>();
160+
final Set<Runnable> added = Collections.synchronizedSet(new HashSet());
161+
final CountDownLatch latch = new CountDownLatch(999);
159162
// Adding 1000 Runnables from different threads
160-
for (int i = 0; i < 1000; ++i) {
161-
final boolean addToSet = i > 0;
162-
final SleepyRunnable sleepyRunnable = new SleepyRunnable(i);
163+
mHandler.post(new SleepyRunnable(0));
164+
for (int i = 0; i < 999; ++i) {
165+
final SleepyRunnable sleepyRunnable = new SleepyRunnable(i+1);
163166
executor.execute(new Runnable() {
164167
@Override
165168
public void run() {
166169
mHandler.post(sleepyRunnable);
167-
if (!addToSet) {
168-
return;
169-
}
170-
synchronized (added) {
171-
added.add(sleepyRunnable);
172-
if (added.size() == 999) {
173-
added.notifyAll(); // #Notify1 - notifying when all runnables been added
174-
}
175-
}
170+
added.add(sleepyRunnable);
171+
latch.countDown();
176172
}
177173
});
178174
}
179175

180-
181176
// Waiting until all runnables added
182177
// Notified by #Notify1
183-
synchronized (added) {
184-
while (added.size() < 999)
185-
added.wait();
186-
}
178+
latch.await();
187179

188-
Field field = mHandler.getClass().getDeclaredField("mRunnables");
189-
field.setAccessible(true);
190-
ChainedRef ref = (ChainedRef) field.get(mHandler);
191-
ref = ref.next;
180+
ChainedRef ref = mHandler.mRunnables.next;
192181
while (ref != null) {
193182
assertTrue("Must remove runnable from chained list: " + ref.runnable, added.remove(ref.runnable));
194183
ref = ref.next;

src/main/java/com/badoo/mobile/util/WeakHandler.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.os.Message;
3030
import android.support.annotation.NonNull;
3131
import android.support.annotation.Nullable;
32+
import android.support.annotation.VisibleForTesting;
3233

3334
import java.lang.ref.WeakReference;
3435
import java.util.concurrent.locks.Lock;
@@ -55,7 +56,8 @@ public class WeakHandler {
5556
private final ExecHandler mExec;
5657
private Lock mLock = new ReentrantLock();
5758
@SuppressWarnings("ConstantConditions")
58-
private final ChainedRef mRunnables = new ChainedRef(mLock, null);
59+
@VisibleForTesting
60+
final ChainedRef mRunnables = new ChainedRef(mLock, null);
5961

6062
/**
6163
* Default constructor associates this handler with the {@link Looper} for the
@@ -382,10 +384,8 @@ private WeakRunnable wrapRunnable(@NonNull Runnable r) {
382384
if (r == null) {
383385
throw new NullPointerException("Runnable can't be null");
384386
}
385-
// In previous version we tried to reuse ChainedRef references from pool
386-
// unfortunately it caused several concurrency issues, so now we don't reuse them
387387
final ChainedRef hardRef = new ChainedRef(mLock, r);
388-
mRunnables.insertAbove(hardRef);
388+
mRunnables.insertAfter(hardRef);
389389
return hardRef.wrapper;
390390
}
391391

@@ -464,8 +464,7 @@ public ChainedRef(@NonNull Lock lock, @NonNull Runnable r) {
464464
this.wrapper = new WeakRunnable(new WeakReference<>(r), new WeakReference<>(this));
465465
}
466466

467-
public void remove() {
468-
final Lock lock = this.lock;
467+
public WeakRunnable remove() {
469468
lock.lock();
470469
try {
471470
if (prev != null) {
@@ -479,9 +478,10 @@ public void remove() {
479478
} finally {
480479
lock.unlock();
481480
}
481+
return wrapper;
482482
}
483483

484-
public void insertAbove(@NonNull ChainedRef candidate) {
484+
public void insertAfter(@NonNull ChainedRef candidate) {
485485
lock.lock();
486486
try {
487487
if (this.next != null) {
@@ -502,19 +502,15 @@ public WeakRunnable remove(Runnable obj) {
502502
try {
503503
ChainedRef curr = this.next; // Skipping head
504504
while (curr != null) {
505-
if (curr.runnable.equals(obj)) {
506-
break;
505+
if (curr.runnable == obj) { // We do comparison exactly how Handler does inside
506+
return curr.remove();
507507
}
508508
curr = curr.next;
509509
}
510-
if (curr == null)
511-
return null;
512-
WeakRunnable result = curr.wrapper;
513-
curr.remove();
514-
return result;
515510
} finally {
516511
lock.unlock();
517512
}
513+
return null;
518514
}
519515
}
520516
}

0 commit comments

Comments
 (0)