Skip to content

Commit ab2fc61

Browse files
committed
Fixed concurrency issue printing statements in the StatusLogger
1 parent 13893bc commit ab2fc61

File tree

1 file changed

+70
-56
lines changed

1 file changed

+70
-56
lines changed

src/javaxt/express/utils/StatusLogger.java

Lines changed: 70 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,22 @@
1313
* messages are written every second and appear in the following format:
1414
* <pre>0 records processed (0 records per second)</pre>
1515
* A percent completion and an estimated time to completion (ETC) is appended
16-
* to the status message if a "totalRecords" counter is given.<br/>
16+
* to the status message if a "totalRecords" counter is given.
17+
* <p>
1718
* The status logger is run in a separate thread. The "recordCounter" is
1819
* updated by the caller. Example:
20+
* </p>
1921
<pre>
22+
//Instantite the StatusLogger with a record counter
2023
AtomicLong recordCounter = new AtomicLong(0);
2124
StatusLogger statusLogger = new StatusLogger(recordCounter);
22-
while (true){
23-
//Execute some process then update the counter
24-
recordCounter.incrementAndGet();
25-
}
25+
26+
//Execute some process then update the counter
27+
...
28+
recordCounter.incrementAndGet();
29+
...
30+
31+
//Shutdown the StatusLogger when finished processing
2632
statusLogger.shutdown();
2733
</pre>
2834
*
@@ -54,59 +60,10 @@ public StatusLogger(AtomicLong recordCounter, AtomicLong totalRecords){
5460
startTime = System.currentTimeMillis();
5561
this.totalRecords = totalRecords==null ? new AtomicLong(0) : totalRecords;
5662

57-
StatusLogger me = this;
63+
5864
r = new Runnable(){
5965
public void run() {
60-
long currTime = System.currentTimeMillis();
61-
double elapsedTime = (currTime-startTime)/1000; //seconds
62-
long x = recordCounter.get();
63-
AtomicLong totalRecords = me.totalRecords;
64-
65-
String rate = "0";
66-
long recordsPerSecond = 0;
67-
try{
68-
recordsPerSecond = Math.round(x/elapsedTime);
69-
if (totalRecords!=null && totalRecords.get()>0){
70-
if (recordsPerSecond>totalRecords.get()) recordsPerSecond = totalRecords.get();
71-
}
72-
rate = StringUtils.format(recordsPerSecond);
73-
}
74-
catch(Exception e){}
75-
76-
int len = statusText.length();
77-
if (!separateMessages){
78-
for (int i=0; i<len; i++){
79-
System.out.print("\b");
80-
}
81-
}
82-
83-
statusText = StringUtils.format(x) + " records processed (" + rate + " records per second)";
84-
85-
86-
if (totalRecords!=null && totalRecords.get()>0){
87-
double p = ((double) x / (double) totalRecords.get());
88-
int percentComplete = (int) Math.round(p*100);
89-
90-
String _etc = "---------- --:-- --";
91-
if (elapsedTime>0 && recordsPerSecond>0){
92-
int timeRemaining = (int) Math.round(((totalRecords.get()-x)/recordsPerSecond)/60);
93-
94-
javaxt.utils.Date etc = new javaxt.utils.Date();
95-
etc.add(timeRemaining, "minutes");
96-
97-
if (percentComplete==100) etc = new javaxt.utils.Date();
98-
if (tz!=null) etc.setTimeZone(tz);
99-
100-
_etc = etc.toString("yyyy-MM-dd HH:mm a");
101-
}
102-
103-
statusText += " " + x + "/" + totalRecords.get() + " " + percentComplete + "% ETC: " + _etc;
104-
}
105-
106-
while (statusText.length()<len) statusText += " ";
107-
108-
109-
System.out.print(statusText + (separateMessages ? "\r\n" : ""));
66+
print(recordCounter);
11067
}
11168
};
11269

@@ -200,4 +157,61 @@ public void shutdown(){
200157
//Clean up
201158
executor.shutdown();
202159
}
160+
161+
162+
//**************************************************************************
163+
//** print
164+
//**************************************************************************
165+
private synchronized void print(AtomicLong recordCounter){
166+
long currTime = System.currentTimeMillis();
167+
double elapsedTime = (currTime-startTime)/1000; //seconds
168+
long x = recordCounter.get();
169+
170+
171+
String rate = "0";
172+
long recordsPerSecond = 0;
173+
try{
174+
recordsPerSecond = Math.round(x/elapsedTime);
175+
if (totalRecords!=null && totalRecords.get()>0){
176+
if (recordsPerSecond>totalRecords.get()) recordsPerSecond = totalRecords.get();
177+
}
178+
rate = StringUtils.format(recordsPerSecond);
179+
}
180+
catch(Exception e){}
181+
182+
int len = statusText.length();
183+
if (!separateMessages){
184+
for (int i=0; i<len; i++){
185+
System.out.print("\b");
186+
}
187+
}
188+
189+
statusText = StringUtils.format(x) + " records processed (" + rate + " records per second)";
190+
191+
192+
if (totalRecords!=null && totalRecords.get()>0){
193+
double p = ((double) x / (double) totalRecords.get());
194+
int percentComplete = (int) Math.round(p*100);
195+
196+
String _etc = "---------- --:-- --";
197+
if (elapsedTime>0 && recordsPerSecond>0){
198+
int timeRemaining = (int) Math.round(((totalRecords.get()-x)/recordsPerSecond)/60);
199+
200+
javaxt.utils.Date etc = new javaxt.utils.Date();
201+
etc.add(timeRemaining, "minutes");
202+
203+
if (percentComplete==100) etc = new javaxt.utils.Date();
204+
if (tz!=null) etc.setTimeZone(tz);
205+
206+
_etc = etc.toString("yyyy-MM-dd HH:mm a");
207+
}
208+
209+
statusText += " " + x + "/" + totalRecords.get() + " " + percentComplete + "% ETC: " + _etc;
210+
}
211+
212+
while (statusText.length()<len) statusText += " ";
213+
214+
215+
System.out.print(statusText + (separateMessages ? "\r\n" : ""));
216+
}
203217
}

0 commit comments

Comments
 (0)