Is there a stopwatch in Java?
On Google I only found code of stopwatches that don't work - they always return 0 milliseconds.
This code I found doesn't work and I don't see why.
public class StopWatch {
private long startTime = 0;
private long stopTime = 0;
private boolean running = false;
public void start() {
this.startTime = System.currentTimeMillis();
this.running = true;
}
public void stop() {
this.stopTime = System.currentTimeMillis();
this.running = false;
}
//elaspsed time in milliseconds
public long getElapsedTime() {
long elapsed;
if (running) {
elapsed = (System.currentTimeMillis() - startTime);
} else {
elapsed = (stopTime - startTime);
}
return elapsed;
}
//elaspsed time in seconds
public long getElapsedTimeSecs() {
long elapsed;
if (running) {
elapsed = ((System.currentTimeMillis() - startTime) / 1000);
} else {
elapsed = ((stopTime - startTime) / 1000);
}
return elapsed;
}
}
You'll find one in
http://commons.apache.org/lang/
It's called
org.apache.commons.lang.time.StopWatch
But it roughly does the same as yours. If you're in for more precision, use
System.nanoTime()
See also this question here:
Time measuring overhead in Java
Use Guava's Stopwatch class.
An object that measures elapsed time in nanoseconds. It is useful to
measure elapsed time using this class instead of direct calls to
System.nanoTime() for a few reasons:
An alternate time source can be substituted, for testing or performance reasons.
As documented by nanoTime, the value returned has no absolute meaning, and can only be interpreted as relative to another timestamp
returned by nanoTime at a different time. Stopwatch is a more
effective abstraction because it exposes only these relative values,
not the absolute ones.
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional
long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
log.info("that took: " + stopwatch); // formatted string like "12.3 ms"
Now you can try something like:
Instant starts = Instant.now();
Thread.sleep(10);
Instant ends = Instant.now();
System.out.println(Duration.between(starts, ends));
Output is in ISO 8601.
Spring provides an elegant org.springframework.util.StopWatch class (spring-core module).
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// Do something
stopWatch.stop();
System.out.println(stopWatch.getTotalTimeMillis());
There's no built in Stopwatch utility but as of JSR-310 (Java 8 Time) you can do this simply.
ZonedDateTime now = ZonedDateTime.now();
// Do stuff
long seconds = now.until(ZonedDateTime.now(), ChronoUnit.SECONDS);
I haven't benchmarked this properly but I would guess using Guava's Stopwatch is more effective.
The code doesn't work because elapsed variable in getElapsedTimeSecs() is not a float or double.
Use System.currentTimeMillis() to get the start time and the end time and calculate the difference.
class TimeTest1 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long total = 0;
for (int i = 0; i < 10000000; i++) {
total += i;
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println(elapsedTime);
}
}
More info at this tutorial
Try this:
/*
* calculates elapsed time in the form hrs:mins:secs
*/
public class StopWatch
{
private Date startTime;
public void startTiming()
{
startTime = new Date();
}
public String stopTiming()
{
Date stopTime = new Date();
long timediff = (stopTime.getTime() - startTime.getTime())/1000L;
return(DateUtils.formatElapsedTime(timediff));
}
}
Use:
StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();
use : com.google.common.base.Stopwatch, its simple and easy.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
example:
Stopwatch stopwatch = new Stopwatch();
stopwatch.start();
"Do something"
logger.debug("this task took " + stopwatch.stop().elapsedTime(TimeUnit.MILLISECONDS) + " mills");
this task took 112 mills
try this
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class millis extends JFrame implements ActionListener, Runnable
{
private long startTime;
private final static java.text.SimpleDateFormat timerFormat = new java.text.SimpleDateFormat("mm : ss.SSS");
private final JButton startStopButton= new JButton("Start/stop");
private Thread updater;
private boolean isRunning= false;
private final Runnable displayUpdater= new Runnable()
{
public void run()
{
displayElapsedTime(System.currentTimeMillis() - millis.this.startTime);
}
};
public void actionPerformed(ActionEvent ae)
{
if(isRunning)
{
long elapsed= System.currentTimeMillis() - startTime;
isRunning= false;
try
{
updater.join();
// Wait for updater to finish
}
catch(InterruptedException ie) {}
displayElapsedTime(elapsed);
// Display the end-result
}
else
{
startTime= System.currentTimeMillis();
isRunning= true;
updater= new Thread(this);
updater.start();
}
}
private void displayElapsedTime(long elapsedTime)
{
startStopButton.setText(timerFormat.format(new java.util.Date(elapsedTime)));
}
public void run()
{
try
{
while(isRunning)
{
SwingUtilities.invokeAndWait(displayUpdater);
Thread.sleep(50);
}
}
catch(java.lang.reflect.InvocationTargetException ite)
{
ite.printStackTrace(System.err);
// Should never happen!
}
catch(InterruptedException ie) {}
// Ignore and return!
}
public millis()
{
startStopButton.addActionListener(this);
getContentPane().add(startStopButton);
setSize(100,50);
setVisible(true);
}
public static void main(String[] arg)
{
new Stopwatch().addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
millis s=new millis();
s.run();
}
}
try this http://introcs.cs.princeton.edu/java/stdlib/Stopwatch.java.html
that's very easy
Stopwatch st = new Stopwatch();
// Do smth. here
double time = st.elapsedTime(); // the result in millis
This class is a part of stdlib.jar
Simple out of the box Stopwatch class:
import java.time.Duration;
import java.time.Instant;
public class StopWatch {
Instant startTime, endTime;
Duration duration;
boolean isRunning = false;
public void start() {
if (isRunning) {
throw new RuntimeException("Stopwatch is already running.");
}
this.isRunning = true;
startTime = Instant.now();
}
public Duration stop() {
this.endTime = Instant.now();
if (!isRunning) {
throw new RuntimeException("Stopwatch has not been started yet");
}
isRunning = false;
Duration result = Duration.between(startTime, endTime);
if (this.duration == null) {
this.duration = result;
} else {
this.duration = duration.plus(result);
}
return this.getElapsedTime();
}
public Duration getElapsedTime() {
return this.duration;
}
public void reset() {
if (this.isRunning) {
this.stop();
}
this.duration = null;
}
}
Usage:
StopWatch sw = new StopWatch();
sw.start();
// doWork()
sw.stop();
System.out.println( sw.getElapsedTime().toMillis() + "ms");
Try this.
public class StopWatch {
private long startTime = 0;
private long stopTime = 0;
public StopWatch()
{
startTime = System.currentTimeMillis();
}
public void start() {
startTime = System.currentTimeMillis();
}
public void stop() {
stopTime = System.currentTimeMillis();
System.out.println("StopWatch: " + getElapsedTime() + " milliseconds.");
System.out.println("StopWatch: " + getElapsedTimeSecs() + " seconds.");
}
/**
* #param process_name
*/
public void stop(String process_name) {
stopTime = System.currentTimeMillis();
System.out.println(process_name + " StopWatch: " + getElapsedTime() + " milliseconds.");
System.out.println(process_name + " StopWatch: " + getElapsedTimeSecs() + " seconds.");
}
//elaspsed time in milliseconds
public long getElapsedTime() {
return stopTime - startTime;
}
//elaspsed time in seconds
public double getElapsedTimeSecs() {
double elapsed;
elapsed = ((double)(stopTime - startTime)) / 1000;
return elapsed;
}
}
Usage:
StopWatch watch = new StopWatch();
// do something
watch.stop();
Console:
StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.
Performetrics provides a convenient Stopwatch class, just the way you need. It can measure wall-clock time and more: it also measures CPU time (user time and system time) if you need.
It's small, free and you can download from Maven Central.
More information and examples can be found here: https://obvj.net/performetrics
Stopwatch sw = new Stopwatch();
sw.start();
// Your code
sw.stop();
sw.printStatistics(System.out);
// Sample output:
// +-----------------+----------------------+--------------+
// | Counter | Elapsed time | Time unit |
// +-----------------+----------------------+--------------+
// | Wall clock time | 85605718 | nanoseconds |
// | CPU time | 78000500 | nanoseconds |
// | User time | 62400400 | nanoseconds |
// | System time | 15600100 | nanoseconds |
// +-----------------+----------------------+--------------+
You can convert the metrics to any time unit (nanoseconds, milliseconds, seconds, etc...)
PS: I am the author of the tool.
You can find a convenient one here:
https://github.com/varra4u/utils4j/blob/master/src/main/java/com/varra/util/StopWatch.java
Usage:
final StopWatch timer = new StopWatch();
System.out.println("Timer: " + timer);
System.out.println("ElapsedTime: " + timer.getElapsedTime());
Try this.
Java Stopwatch Fully Working Solution
Here you will get a fully working solution.
Just a snippet from the above-linked solution:
You can create a class like below code and use this class' start and stop method before and after the code section, you want to measure the time taken.
public class Stopwatch{
private long startTime;
private long stopTime;
/**
starting the stop watch.
*/
public void start(){
startTime = System.nanoTime();
}
/**
stopping the stop watch.
*/
public void stop()
{ stopTime = System.nanoTime(); }
/**
elapsed time in nanoseconds.
*/
public long time(){
return (stopTime - startTime);
}
public String toString(){
return "elapsed time: " + time() + " nanoseconds.";
}
}
Thank you.
Try this...
import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;
public class StopwatchTest {
public static void main(String[] args) throws Exception {
Stopwatch stopwatch = Stopwatch.createStarted();
Thread.sleep(1000 * 60);
stopwatch.stop(); // optional
long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
System.out.println("Time in milliseconds "+millis);
System.out.println("that took: " + stopwatch);
}
}
I have created a Stopwatch that has everything you might need in it.
I even documented it!
And I also compiled it for faster usage.
Here's an example:
//...
//For demo only!
public static void main(String[]a){
final Stopwatch stopwatch=new Stopwatch();
stopwatch.start();
try{
java.lang.Thread.sleep(1000);
}catch(Exception e){}
stopwatch.split();
System.out.println("Time elapsed in nanoseconds: "+stopwatch.getTimeElapsed());
System.out.println("Time elapsed in milliseconds: "+stopwatch.getTimeElapsed(Stopwatch.millis));
System.out.println("Time elapsed in seconds: "+stopwatch.getTimeElapsed(Stopwatch.seconds));
try{
java.lang.Thread.sleep(1000);
}catch(Exception e){}
stopwatch.split();
final long[][] laps=stopwatch.getLaps();
for(long[] lap:laps){
System.out.println(java.util.Arrays.toString(lap));
}
}
//...
This is not for promotion, made this to help people not waste their time in coding classes themselves!
Related
I've implemented a stopwatch class for my own little library and tested it by executing the following snippet:
public class Main {
public static void main(String[] args) throws Exception {
StopWatch sw = new StopWatch();
sw.start();
Thread.sleep(3000);
sw.stop();
System.out.println(sw.getMilli());
System.out.println(sw.getDuration().getNano());
System.out.println(sw.getDuration().getSeconds());
}
}
I get the following result:
20
2011600
3
You can see that the numbers differ. I checked my StopWatch class round about 10 times, but I cant find mistakes. Can you find them?
This is my stopwatch-implementation:
import java.time.Instant;
import java.time.Duration;
public class StopWatch {
private Instant startDate;
private Instant stopDate;
public StopWatch() {
reset();
}
public void start() {
if (startDate == null) {
startDate = Instant.now();
}
}
public void stop() {
if (stopDate == null && startDate != null) {
stopDate = Instant.now();
}
}
public void reset() {
startDate = null;
stopDate = null;
}
public Duration getDuration() {
if (startDate != null && stopDate != null) {
return Duration.between(startDate, stopDate);
}
return null;
}
public long getMilli() {
if (startDate != null && stopDate != null) {
return Duration.between(startDate, stopDate).getNano() / 1000000L;
}
return 0;
}
}
I missunderstood how objects of the class Duration work. getNano() does not return the total amount of nanoseconds between a range, but the rest of nanoseconds that do not fit into a whole second. I deleted getDuration() and reimplemented getMilli() like that:
public long getMilli() {
if (startDate != null && stopDate != null) {
Duration duration = Duration.between(startDate, stopDate);
long nanos = duration.getSeconds() * 1000000000 + duration.getNano();
return nanos / 1000000;
}
return 0;
}
Hello I have an application calculate time and throwing an event according that. I would like to make my application with thread safe using longadder or whatever is suitable.
my class below;
#Autowired
EventListenerConfiguration eventListenerConfiguration;
private volatile long lastReceivedMessage = System.currentTimeMillis();
public void consume(String message) Integer partition,
(Headers.OFFSET) Long offset, Acknowledgment ack) {
lastReceivedMessage = System.currentTimeMillis();
try {
seervice.processMessage(message, ack, null);
} catch (ParseException e) {
logger.error(e.getMessage());
}
}
#Scheduled(fixedDelayString = "${listenScheduled}", initialDelay = 100000)
private void distanceBetweenLastReceivedMessageAndCurrentTime() {
long currentTime = System.currentTimeMillis() - lastReceivedMessage;
if (currentTime >= EventListenerConfiguration .getTotalMilliSecondTimeForError()) {
EventUtil.publishEvent(THROW_ERROR_EVENT, EventSeverityStatus.ERROR, EventTypeStatus.CUSTOM, null);
} else (currentTime >= EventListenerConfiguration.getTotalMilliSecondTimeForWarn()) {
EventUtil.publishEvent(THROW_WARN_EVENT, EventSeverityStatus.WARN, EventTypeStatus.CUSTOM, null);
}
}
so basicly how to convert my code without changing much to longAdder and also perform currentTime-lastReceiveMessage
Thank you
Good Evening. It appears that your issue is largely that lastReceivedMessage is a protected resource used by two threads. Whatever is running the consume method generates it, and then the Spring-Generated #scheduled thread consumes it.
Adding the volatile keyword will not prevent the code from reading the field. It will only prevent the code from caching the variable. (Read up on volatile https://www.geeksforgeeks.org/volatile-keyword-in-java/) If you want to treat the #Scheduled block as a critical region, and prevent the updating of the lastRecievedMessage until it is complete, I would recommend the following:
private volatile long lastReceivedMessage = System.currentTimeMillis();
private Semaphore resourceLock = new Semaphore(1);
public void consume(String message) Integer partition,
(Headers.OFFSET) Long offset, Acknowledgment ack) {
resourceLock.acquireUninterruptibly();
try {
lastReceivedMessage = System.currentTimeMillis();
} finally {
resourceLock.release();
}
try {
seervice.processMessage(message, ack, null);
} catch (ParseException e) {
logger.error(e.getMessage());
}
}
#Scheduled(fixedDelayString = "${listenScheduled}", initialDelay = 100000)
private void distanceBetweenLastReceivedMessageAndCurrentTime() {
long currentTime = 0;
resourceLock.acquireUninterruptibly();
try {
currentTime = System.currentTimeMillis() - lastReceivedMessage;
if (currentTime >= EventListenerConfiguration .getTotalMilliSecondTimeForError()) {
EventUtil.publishEvent(THROW_ERROR_EVENT, EventSeverityStatus.ERROR, EventTypeStatus.CUSTOM, null);
} else (currentTime >= EventListenerConfiguration.getTotalMilliSecondTimeForWarn()) {
EventUtil.publishEvent(THROW_WARN_EVENT, EventSeverityStatus.WARN, EventTypeStatus.CUSTOM, null);
}
} finally {
resourceLock.release();
}
}
Code 1: In this code, I use the System.out.println(); to get the value changed by other thread instead of using volatile.
package edu.seu.juc.vol;
import edu.seu.juc.annotation.ThreadNotSafe;
import java.lang.management.ManagementFactory;
/**
* #author: zs.sun
* Create at: 2020/5/24 10:31
* #Package: edu.seu.juc.vol
* #ProjectName: af-study
* #Description:
*/
#ThreadNotSafe
public class TestVolatile01 {
public static void main(String[] args) {
Long startTime = System.currentTimeMillis();
ThreadDemo td = new ThreadDemo();
new Thread(td).start();
while (true) {
if (td.isFlag()) {
System.out.println("--------------------------");
break;
}
System.out.println(); // to see the value changed by other thread
}
System.out.println("total: " + (System.currentTimeMillis() - startTime));
System.out.println("CPU time: " + ManagementFactory.getThreadMXBean().getThreadCpuTime(Thread.currentThread().getId())
/ (1000 * 1000));
}
private static class ThreadDemo implements Runnable {
private boolean flag = false;
#Override
public void run() {
try {
Thread.sleep(2000);
flag = true;
System.out.println("flag = " + isFlag());
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
}
Result1
...(some blank lines)
flag = true
--------------------------
total: 2010
CPU time: 875
Code 2: In this code, I use the volatile to get the value changed by other thread.
package edu.seu.juc.vol;
import edu.seu.juc.annotation.ThreadSafe;
import java.lang.management.ManagementFactory;
/**
* #author: zs.sun
* Create at: 2020/5/24 10:31
* #Package: edu.seu.juc.vol
* #ProjectName: af-study
* #Description:
*/
#ThreadSafe
public class TestVolatile02 {
public static void main(String[] args) {
Long startTime = System.currentTimeMillis();
ThreadDemo td = new ThreadDemo();
new Thread(td).start();
while (true) {
if (td.isFlag()) {
System.out.println("--------------------------");
break;
}
}
System.out.println("total: " + (System.currentTimeMillis() - startTime));
System.out.println("CPU time: " + ManagementFactory.getThreadMXBean().getThreadCpuTime(Thread.currentThread().getId())
/ (1000 * 1000));
}
private static class ThreadDemo implements Runnable {
private volatile boolean flag = false;
#Override
public void run() {
try {
Thread.sleep(2000);
flag = true;
System.out.println("flag = " + isFlag());
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
}
Result 2
--------------------------
total: 2005
flag = true
CPU time: 1968
Can anyone tell me why the CPU time is different?
In my opinion, the main thread in both Codes keeps the CPU all the time, but the Code 1 keeps the absolutely less CPU time.
In Code 1, time spent in the OS Kernel to print the blank line (and maybe scroll the terminal window), is time not spent in the Java thread, so not all the CPU time is counted when printing.
The loop in Code 2 is a pure CPU loop, so all the time is spent by the Java thread.
I have to solve an homework, this is the question:
Look this program, run it and found the problem then fix it.
this is the program:
package serie02;
import java.util.ArrayList;
class S2Es1Timer {
private long startTime = -1;
private long stopTime = -1;
final protected void start() {
startTime = System.currentTimeMillis();
}
final protected void stop() {
stopTime = System.currentTimeMillis();
}
final public long getElapsedTime() {
if (startTime < 0 || stopTime < 0)
return 0;
return stopTime - startTime;
}
}
class S2Es1SharedState {
boolean sharedState = false;
}
class S2Es1Worker implements Runnable {
private static final long START_VALUE = 1000000000;
private final int id;
private final S2Es1Timer timer;
private final S2Es1SharedState state;
private long localCounter = START_VALUE;
public S2Es1Worker(final int id, final S2Es1SharedState state) {
this.id = id;
timer = new S2Es1Timer();
this.state = state;
log("created");
}
#Override
public void run() {
timer.start();
while (--localCounter > 0) {
if (state.sharedState) {
timer.stop();
log("sharedState has already been set by another worker. localCounter: "
+ ((100.0 * localCounter) / START_VALUE)
+ " % from goal");
return;
}
}
// richiedi accesso esclusivo per scrittura
state.sharedState = true;
timer.stop();
log("sharedState has been set");
}
final protected void log(final String s) {
System.out.println(this.getClass().getSimpleName() + id + ": " + s);
}
final protected void logElapseTime() {
log("time: " + timer.getElapsedTime() + " ms");
}
}
public class S2Esercizio1 {
private final static int NUM_WORKERS = 10;
public static void main(final String[] args) {
final S2Es1Timer mainTimer = new S2Es1Timer();
final ArrayList<Thread> threads = new ArrayList<Thread>();
final ArrayList<S2Es1Worker> workers = new ArrayList<S2Es1Worker>();
final S2Es1SharedState myShare = new S2Es1SharedState();
// Crea 10 Workers
for (int i = 0; i < NUM_WORKERS; i++) {
final S2Es1Worker worker = new S2Es1Worker(i, myShare);
workers.add(worker);
threads.add(new Thread(worker));
}
System.out.println("Simulation started");
System.out.println("------------------------------------");
mainTimer.start();
// Fa partire tutte le threads
for (final Thread t : threads)
t.start();
try {
// Attende che tutte le threads terminano
for (final Thread t : threads)
t.join();
} catch (final InterruptedException e) {
/* Unhandled exception */
}
mainTimer.stop();
System.out.println("------------------------------------");
for (final S2Es1Worker worker : workers)
worker.logElapseTime();
System.out.println("Simulation time: " + mainTimer.getElapsedTime()
+ " ms");
System.out.println("Simulation finished");
}
}
this is the output:
S2Es1Worker0: created
S2Es1Worker1: created
S2Es1Worker2: created
S2Es1Worker3: created
S2Es1Worker4: created
S2Es1Worker5: created
S2Es1Worker6: created
S2Es1Worker7: created
S2Es1Worker8: created
S2Es1Worker9: created
Simulation started
------------------------------------
S2Es1Worker6: sharedState has been set
S2Es1Worker7: sharedState has been set
S2Es1Worker3: sharedState has been set
S2Es1Worker5: sharedState has been set
S2Es1Worker9: sharedState has been set
S2Es1Worker0: sharedState has been set
S2Es1Worker4: sharedState has been set
S2Es1Worker8: sharedState has been set
S2Es1Worker1: sharedState has been set
S2Es1Worker2: sharedState has been set
------------------------------------
S2Es1Worker0: time: 2300 ms
S2Es1Worker1: time: 2401 ms
S2Es1Worker2: time: 2420 ms
S2Es1Worker3: time: 1921 ms
S2Es1Worker4: time: 2332 ms
S2Es1Worker5: time: 2169 ms
S2Es1Worker6: time: 909 ms
S2Es1Worker7: time: 1847 ms
S2Es1Worker8: time: 2305 ms
S2Es1Worker9: time: 2237 ms
Simulation time: 2422 ms
Simulation finished
I think is a problem of visibility, i mean when the first thread finish the loop and set the shared mutable variable sharedState to true, the others threads continue to loop because they have a "dirty read" in the cache cpu (i have 4 cpu).
So the only good thing that i can do is set the sharedState variable with the key volatile. in this way every thread reads the correct value. I lost time because this value now is catched by the main memory instead of the cpu cache.
Another solution could be: to use ReentrantReadWriteLock.
So the class S2Es1SharedState could be writed in this way:
class S2Es1SharedState {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
boolean sharedState = false;
public boolean getSharedState() {
readLock.lock();
try {
return sharedState;
} finally {
readLock.unlock();
}
}
public void setSharedState() {
writeLock.lock();
try {
this.sharedState = true;
}
finally {
writeLock.unlock();
}
}
}
This solution i think work because the lock also give a correct visibility but i think take a lot of time because in this way inside the loop i don't use the cache cpu but just the main memory. and this operation need time.
I'm not sure about my analysis, for this reason i prefer to ask to you.
I am trying to do something conceptually simple...
We have multiple portlets loading on a Dashboard. I need to measure the load time that each takes. I have implemented a simple StopWatch class, and need to run multiple instance of it simultaneously, for each portlet, while the Dashboard is loading.
So the parameters supplied will be:
The portlet name
The element to be checked, indicating a successful load.
Here is the StopWatch class:
public class StopWatch implements Runnable {
private long startTime;
private long stopTime;
private String tElement;
private String tPortletName;
public StopWatch(String portletName,String element) {
tElement = element;
tPortletName = portletName;
}
public void start() {
startTime = System.currentTimeMillis();
}
public void stop() {
stopTime = System.currentTimeMillis();
}
public long getTime() {
return stopTime - startTime;
}
#Override
public void run() {
selenium.selectFrame(tPortletName);
StopWatch sw = new StopWatch();
sw.start();
while (selenium.isElementPresent(tElement)==false)
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
sw.stop();
long time = sw.getTime();
System.out.println(tPortletName+" load time="+time);
}
}
In the calling program,
StopWatch sw1 = new StopWatch(portlet1,element1);
StopWatch sw2 = new StopWatch(portlet2,element2);
ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
threadExecutor.execute(sw1); // start task1
threadExecutor.execute(sw2); // start task2
Upon running this, I get the following exception:
com.thoughtworks.selenium.SeleniumException: ERROR Server Exception: commandHolder got filled during execution of doCommandWithoutWaitingForAReponse
Any clues on what causes this?
Most likely the reason is that you are sending commands faster then Selenium can process them.
Anyway this approach should not work since DefaulSelenium and other Selenium classes are not synchronized so if you most likely you will get deadlocks or unpredictable results.
I think you will have to test this in two steps: load dashboard, wait for first portlet, then reload dashboard and wait for second portlet. Do all of this in the main thread, something like:
private void waitForPortlet(String portletName, String element) {
long startTime = System.currentTimeMillis();
while (selenium.isElementPresent(element) == false)
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
long stopTime = System.currentTimeMillis();
System.out.println(portletName + " load time=" + (stopTime - startTime));
}
And use:
waitForPortlet(name1, element1);
selenium.refresh();
waitForPortlet(name2, element2);