-
Notifications
You must be signed in to change notification settings - Fork 1
/
ReEntrantLockedAsyncTask.java
190 lines (154 loc) · 4.38 KB
/
ReEntrantLockedAsyncTask.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import android.os.AsyncTask;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/*
* re-entrant lock example in async task await/signall on lock condition
* made by @ceph3us
* https://github.com/c3ph3us/examples/ReEntrantLockedAsyncTask.java
*/
public class ReEntrantLockedAsyncTask extends AsyncTask<Void, Long, Void> {
/**
* flag for while() loop to break it on given condition
*/
private volatile boolean isDataStillNeeded = true;//mutex for data
/**
* re-entrant lock
*/
private final ReentrantLock lock = new ReentrantLock();
/**
* condition for lock
*/
private final Condition dataAcquired = lock.newCondition();
/**
* flag to hold lock state
*/
private boolean isLockAcquired;
@Override
protected Void doInBackground(Void... params) {
/**
* example temporary placeholder
* for gathered data
* */
long someProgressData = 0;
try {
/**
* try get interruptibility lock
* to be able to call await on condition
* */
lock.lockInterruptibly();
/**
* create while() loop
* to gather data
* loop will be broken by
* changing given flag state
*/
while (isDataStillNeeded) {
/** get lock state */
isLockAcquired = lock.isHeldByCurrentThread();
/** check for lock state */
if (isLockAcquired) {
/**
* example gathered data
* increase data counter
* */
someProgressData++;
/** publish gathered result */
publishProgress(someProgressData);
/**
* call await on condition
* for given lock after lock was acquired
* */
dataAcquired.await();
}
}
} catch (InterruptedException e) {
/**
* her we catch
* lock interrupt exception
*/
e.printStackTrace();
} finally {
/**
* this block is proceed
* after interrupt exception occurred
* or task was finish by normal flow
* after flag state was set to false
* */
/**
* unlock lock
* to be able to finish task
* */
lock.unlock();
}
/** return from task */
return null;
}
@Override
protected void onProgressUpdate(Long... resultList) {
/**
* example do some work witch check result
* & change while loop flag state
* */
if (resultList[0] > 1000) {
/**
* we don't need more data
* change flat state
* */
isDataStillNeeded = false;
}
/**
* call method which will call
* condition signal to wake-up thread
* */
retry();
}
/**
* on task canceled
*/
@Override
protected void onCancelled() {
/**
* NOTE Make sure to clean up
* if the task is killed
* */
terminateTask();
}
/**
* the task will only finish
* when we call this method
* or by thrown interrupt exception
*/
private void terminateTask() {
/** unlock lock */
lock.unlock();
}
/**
* method to wake-up thread
* locke by lock.lockInterruptibly()
* after condition await was called
* on try {} block in while() loop
*/
public void retry() {
/**
* try get lock
* for current calling thread
* */
lock.lock();
/** get lock state */
isLockAcquired = lock.isHeldByCurrentThread();
/** check if lock was acquired */
if (isLockAcquired) {
/**
* if so
* send condition signal
* to wake-up awaiting thread
* */
dataAcquired.signal();
}
/**
* unlock thread locked
* for calling on condition signal
* */
lock.unlock();
}
}