Skip to content

Commit 22b602c

Browse files
authored
Merge pull request #476 from YangSen-qn/optimize-transaction-manager
Optimize transaction manager
2 parents 88ed3f6 + e27461c commit 22b602c

File tree

3 files changed

+58
-26
lines changed

3 files changed

+58
-26
lines changed

library/src/androidTest/java/com/qiniu/android/TransactionManagerTest.java renamed to library/src/androidTest/java/com/qiniu/android/transaction/TransactionManagerTest.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
package com.qiniu.android;
1+
package com.qiniu.android.transaction;
22

3-
import com.qiniu.android.transaction.TransactionManager;
3+
import com.qiniu.android.BaseTest;
44
import com.qiniu.android.utils.LogUtil;
5+
import com.qiniu.android.utils.Utils;
56

67
import java.util.Date;
78

@@ -51,19 +52,45 @@ public void run() {
5152
});
5253

5354
TransactionManager manager = TransactionManager.getInstance();
55+
56+
int transactionCountBefore = manager.transactionList.size();
57+
long actionCountBefore = manager.actionCount;
5458
manager.addTransaction(normal);
5559
manager.addTransaction(time);
5660

5761

62+
// 由于事务堆积,执行可能会延后
5863
wait(new WaitConditional() {
5964
@Override
6065
public boolean shouldWait() {
61-
return executedTransaction[0];
66+
return !executedTransaction[0];
6267
}
63-
}, 60);
68+
}, 5 * 60);
6469

6570
wait(null, 6);
6671

72+
String leftTransactionName = "";
73+
for (TransactionManager.Transaction t : manager.transactionList) {
74+
leftTransactionName += " " + t.name + " ";
75+
}
76+
int transactionCountAfter = manager.transactionList.size();
77+
78+
long timestamp = Utils.currentSecondTimestamp();
79+
String assertInfo = "manager action count before:" + actionCountBefore;
80+
assertInfo += " manager action count after:" + manager.actionCount;
81+
assertInfo += " manager transaction count before:" + transactionCountBefore;
82+
assertInfo += " manager transaction count after:" + transactionCountAfter;
83+
assertInfo += " manager left transaction:" + leftTransactionName;
84+
assertInfo += " normal.executedCount:" + normal.executedCount;
85+
assertInfo += " normal nextExecutionTime:" + normal.nextExecutionTime;
86+
assertInfo += " now:" + timestamp;
87+
assertInfo += " should action:" + normal.shouldAction();
88+
assertInfo += " maybeCompleted:" + normal.maybeCompleted();
89+
90+
assertTrue("timestamp:: " + assertInfo, normal.nextExecutionTime < timestamp);
91+
assertTrue("maybeCompleted:: " + assertInfo, normal.maybeCompleted());
92+
assertEquals("executedCount:: " + assertInfo, 1, normal.executedCount);
93+
6794
boolean exist = manager.existTransactionsForName(normalName);
6895
assertFalse(exist);
6996
exist = manager.existTransactionsForName(timeName);

library/src/main/java/com/qiniu/android/transaction/TransactionManager.java

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.qiniu.android.utils.Utils;
44

55
import java.util.ArrayList;
6-
import java.util.List;
76
import java.util.Timer;
87
import java.util.TimerTask;
98
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -14,10 +13,12 @@
1413
public class TransactionManager {
1514

1615
/// 事务链表
17-
private final ConcurrentLinkedQueue<Transaction> transactionList = new ConcurrentLinkedQueue<>();
16+
protected final ConcurrentLinkedQueue<Transaction> transactionList = new ConcurrentLinkedQueue<>();
1817
/// 事务定时器
1918
private Timer timer;
2019

20+
protected long actionCount = 0;
21+
2122
private static final TransactionManager transactionManager = new TransactionManager();
2223

2324
private TransactionManager() {
@@ -28,9 +29,8 @@ public static TransactionManager getInstance() {
2829
}
2930

3031
/// 根据name查找事务
31-
public synchronized ArrayList<Transaction> transactionsForName(String name) {
32+
public ArrayList<Transaction> transactionsForName(String name) {
3233
ArrayList<Transaction> arrayList = new ArrayList<>();
33-
Transaction[] transactionList = this.transactionList.toArray(new Transaction[0]);
3434
for (Transaction transaction : transactionList) {
3535
if ((name == null && transaction.name == null) || (transaction.name != null && transaction.name.equals(name))) {
3636
arrayList.add(transaction);
@@ -40,9 +40,8 @@ public synchronized ArrayList<Transaction> transactionsForName(String name) {
4040
}
4141

4242
/// 是否存在某个名称的事务
43-
public synchronized boolean existTransactionsForName(String name) {
43+
public boolean existTransactionsForName(String name) {
4444
boolean isExist = false;
45-
Transaction[] transactionList = this.transactionList.toArray(new Transaction[0]);
4645
for (Transaction transaction : transactionList) {
4746
if ((name == null && transaction.name == null) || (transaction.name != null && transaction.name.equals(name))) {
4847
isExist = true;
@@ -53,7 +52,7 @@ public synchronized boolean existTransactionsForName(String name) {
5352
}
5453

5554
/// 添加一个事务
56-
public synchronized void addTransaction(Transaction transaction) {
55+
public void addTransaction(Transaction transaction) {
5756
if (transaction == null) {
5857
return;
5958
}
@@ -62,7 +61,7 @@ public synchronized void addTransaction(Transaction transaction) {
6261
}
6362

6463
/// 移除一个事务
65-
public synchronized void removeTransaction(Transaction transaction) {
64+
public void removeTransaction(Transaction transaction) {
6665
if (transaction == null) {
6766
return;
6867
}
@@ -78,7 +77,7 @@ public synchronized void performTransaction(Transaction transaction) {
7877
if (!transactionList.contains(transaction)) {
7978
transactionList.add(transaction);
8079
}
81-
transaction.createTime = Utils.currentSecondTimestamp() - transaction.interval;
80+
transaction.nextExecutionTime = Utils.currentSecondTimestamp();
8281
}
8382

8483
/// 销毁资源 清空事务链表 销毁常驻线程
@@ -89,11 +88,6 @@ public synchronized void destroyResource() {
8988

9089

9190
private void handleAllTransaction() {
92-
Transaction[] transactionList = null;
93-
synchronized (this) {
94-
transactionList = this.transactionList.toArray(new Transaction[0]);
95-
}
96-
9791
for (Transaction transaction : transactionList) {
9892
handleTransaction(transaction);
9993
if (transaction.maybeCompleted()) {
@@ -126,6 +120,7 @@ private void invalidateTimer() {
126120
}
127121

128122
private void timerAction() {
123+
actionCount += 1;
129124
handleAllTransaction();
130125
}
131126

@@ -150,9 +145,11 @@ public static class Transaction {
150145
private final int interval;
151146
// 创建时间
152147
private long createTime;
148+
// 下一次需要执行的时间
149+
protected long nextExecutionTime;
153150

154151
// 已执行次数
155-
private long executedCount = 0;
152+
protected long executedCount = 0;
156153
private boolean isExecuting = false;
157154

158155

@@ -166,6 +163,7 @@ public Transaction(String name,
166163
this.interval = 0;
167164
this.actionHandler = actionHandler;
168165
this.createTime = Utils.currentSecondTimestamp();
166+
this.nextExecutionTime = this.createTime + after;
169167
}
170168

171169

@@ -180,20 +178,21 @@ public Transaction(String name,
180178
this.interval = interval;
181179
this.actionHandler = actionHandler;
182180
this.createTime = Utils.currentSecondTimestamp();
181+
this.nextExecutionTime = this.createTime + after;
183182
}
184183

185-
private boolean shouldAction() {
184+
protected boolean shouldAction() {
186185
long currentTime = Utils.currentSecondTimestamp();
187186
if (this.type == TransactionTypeNormal) {
188-
return executedCount < 1 && (currentTime - createTime) >= after;
187+
return executedCount < 1 && currentTime >= nextExecutionTime;
189188
} else if (this.type == TransactionTypeTime) {
190-
return (currentTime - createTime) >= (executedCount * interval + after);
189+
return currentTime >= nextExecutionTime;
191190
} else {
192191
return false;
193192
}
194193
}
195194

196-
private boolean maybeCompleted() {
195+
protected boolean maybeCompleted() {
197196
if (this.type == TransactionTypeNormal) {
198197
return executedCount > 0;
199198
} else if (this.type == TransactionTypeTime) {
@@ -208,9 +207,15 @@ private synchronized void handleAction() {
208207
return;
209208
}
210209
if (actionHandler != null) {
211-
executedCount += 1;
212210
isExecuting = true;
213-
actionHandler.run();
211+
executedCount += 1;
212+
213+
try {
214+
actionHandler.run();
215+
} catch (Exception ignored) {
216+
}
217+
218+
nextExecutionTime = Utils.currentSecondTimestamp() + interval;
214219
isExecuting = false;
215220
}
216221
}

library/src/main/java/com/qiniu/android/utils/Utils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public static long currentTimestamp() {
109109

110110
// 单位:秒
111111
public static long currentSecondTimestamp() {
112-
return new Date().getTime() / 1000;
112+
return currentTimestamp() / 1000;
113113
}
114114

115115
/// 两个时间的时间段 单位:毫秒

0 commit comments

Comments
 (0)