how to get actual thread execution time in java - java

I am trying to measure the time that a thread takes to execute.
I have created a sample programme
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class Sample {
public static void main(String[] args ) {
ThreadPoolExecutor exec = (ThreadPoolExecutor)Executors.newFixedThreadPool(1000);
for(int i=0; i<1000; i++) {
exec.execute(new Runnable() {
#Override
public void run() {
long start = System.currentTimeMillis();
try{
Thread.sleep(10000);
} catch(Exception ex) {
ex.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("[Sample] Thread id : " + Thread.currentThread().getId() + ", time : " + (end - start));
}
});
}
}
}
Each thread sleeps for 10 seconds. So the duration = (end - start) should be 10000. But some threads are taking more time than expected. I am guessing this also includes thread switching time and and blocking time. Is there a way to measure the exectution time in threaded programme in JAVA?
The thing is that I have a programme that makes network calls in threads. So even if the socket time out is say 60 seconds, the thread execution time is close to 2 minutes. My guess is that the above way of calculating execution time also accounts for thread switching time and blocking time. It is not measuring the actual thread execution time
Thanks.

For such cases I use JavaVisualVM, it is a very very handy tool for finding concurrency issues.
I ran your code locally and this is what visual VM shows me.
All of the threads have exactly the same sleep time, so the differences we are seeing in the console log are probably misleading.

Related

Threads in Java - Sum of N numbers

I tried to perform sum of N numbers using conventional method and also using threads to see the performance of threads. I see that the conventional method runs faster than the thread based.
My plan is to break down the upper limit(N) into ranges then run a thread for each range and finally add the sum calculated from each thread.
stats in milliseconds :
248
500000000500000000
-----same with threads------
498
500000000500000000
Here I see the approach using threads took ~500 milliseconds and conventional method took only ~250 seconds.
I wanted to know If I am correctly implementing threads for this problem.
Thanks
code :
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyThread implements Runnable {
private int from , to , sum;
public MyThread(long from , long to) {
this.from = from;
this.to = to;
sum = 0;
}
public void run() {
for(long i=from;i<=to;i++) {
sum+=i;
}
}
public long getSum() {
return this.sum;
}
}
public class exercise {
public static void main(String args[]) {
long startTime = System.currentTimeMillis();
long sum = 0;
for(long i=1;i<=1000000000;i++) {
sum+=i;
}
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime); //Total execution time in milli seconds
System.out.println(duration);
System.out.println(sum);
System.out.println("-----same with threads------");
ExecutorService executor = Executors.newFixedThreadPool(5);
MyThread one = new MyThread(1, 100000);
MyThread two = new MyThread(100001, 10000000);
MyThread three = new MyThread(10000001, 1000000000);
startTime = System.currentTimeMillis();
executor.execute(one);
executor.execute(two);
executor.execute(three);
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
long thsum = one.getSum() + two.getSum() + three.getSum();
System.out.println(thsum);
}
}
It only makes sense to split the work into multiple threads when each thread is assigned the same amount of work.
In your case, the first thread does almost nothing, the second thread does almost 1% of the work, and the third thread does 99% of the work.
Therefore, you pay the overhead for running multiple threads without benefiting from the parallel execution.
Splitting the work evenly, as follows, should yield better results:
MyThread one = new MyThread(1, 333333333);
MyThread two = new MyThread(333333334, 666666667);
MyThread three = new MyThread(666666668, 1000000000);
The multithread part of your example includes the time for thread creation. Thread creation is an expensive operation and I presume that it is responsible for a large share of the difference between the single thread and multithread approaches.
Your question was if you are correctly implementing the threads. Did you mean implementing the runnable tasks? If so, I wonder why you have distributed the number ranges so unevenly. The task three seems to be far bigger than the others and as a result the performance will be close to a single thread version however you choose to set up the threads.

Java Timer/ScheduledExecutor appears to have a minimum resolution of 10 milliseconds

I'm trying to schedule a task with a fixed-delay repetition, where the delay is 1 millisecond, and it appears that with both the Timer and the ScheduledThreadPoolExecutor classes, the best I can do is 10 millseconds. I'm not expecting to get exactly 1 millisecond resolution, but I wasn't expecting an almost perfect 10 millisecond resolution. Here's a simple class that I put together to test what's going on:
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class SchedTest
{
private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
public static void main(String[] args)
{
int type = Integer.parseInt(args[0]);
switch(type)
{
case 0:
ScheduledThreadPoolExecutor e = new ScheduledThreadPoolExecutor(1);
e.scheduleWithFixedDelay(new Runnable()
{
#Override
public void run()
{
System.out.println("executor " + sdf.format(new Date()));
}
}, 0, 1, TimeUnit.MILLISECONDS);
break;
case 1:
Timer t = new Timer();
TimerTask task = new TimerTask()
{
#Override
public void run()
{
System.out.println("timer " + sdf.format(new Date()));
}
};
t.schedule(task, new Date(), 1);
break;
case 2:
Thread th = new Thread()
{
#Override
public void run()
{
while(true)
{
System.out.println("thread " + sdf.format(new Date()));
try
{
Thread.sleep(1);
}
catch(Exception e)
{
//
}
}
}
};
th.start();
break;
}
}
}
The output that I get from this class looks like this:
executor 11:52:05.202
executor 11:52:05.212
executor 11:52:05.222
executor 11:52:05.232
executor 11:52:05.242
executor 11:52:05.252
executor 11:52:05.262
executor 11:52:05.272
executor 11:52:05.282
executor 11:52:05.292
executor 11:52:05.302
timer 11:52:08.009
timer 11:52:08.019
timer 11:52:08.029
timer 11:52:08.039
timer 11:52:08.049
timer 11:52:08.059
timer 11:52:08.069
timer 11:52:08.079
timer 11:52:08.089
timer 11:52:08.099
timer 11:52:08.109
thread 11:52:13.020
thread 11:52:13.021
thread 11:52:13.022
thread 11:52:13.023
thread 11:52:13.024
thread 11:52:13.025
thread 11:52:13.026
thread 11:52:13.027
thread 11:52:13.028
thread 11:52:13.029
thread 11:52:13.030
My understanding of the fixed-delay is that the time between two executions of the task should be timeTakenByTask + delay - so I'm not sure how that's adding up to 10 milliseconds. What am I missing here?
I'm running with JDK 1.8.0_131 on a Windows 7 laptop.
Edit
If I run the following:
for(int x = 0;x < 10000;x++)
{
System.out.println(System.currentTimeMillis());
}
The output that I get is almost always at a 10ms resolution: that is, my output looks like the following numbers (repeated several times):
1
516212971144
1516212971144
1516212971144
...
1516212971154
1516212971154
1516212971154
...
1516212971164
1516212971164
1516212971164
...
1516212971174
etc.
If I run long enough, occasionally I'll get one response that is actually 1ms between them, but 99% of the time, when the number changes it does so in 10ms increments. So I think that #VGR has it right: as Timer seems to be using System.currentTimeMillis() to keep track of time - and it's likely that ScheduledThreadPoolExecutor is as well - the granularity of that call determines how often the tasks can execute, and as #VGR noted, the docs say that granularity can vary. My machine must be one that has a 10ms granularity.
From the documentation for System.currentTimeMillis():
Note that while the unit of time of the return value is a millisecond, the granularity of the value depends on the underlying operating system and may be larger. For example, many operating systems measure time in units of tens of milliseconds.
Even if ScheduledThreadPoolExecutor weren’t using System.currentTimeMillis() directly, the granularity limitation lies with the native system, so using something like, say, Object.wait probably wouldn’t improve things.
See the specification: ScheduledThreadPoolExecutor which says:
Delayed tasks execute no sooner than they are enabled, but without any
real-time guarantees about when, after they are enabled, they will
commence.
The actual delay depends on factors such what else is going on in your computer, the operating system, the hardware and others.

java - Simple calculation takes longer in multi threads than in single thread

I'm trying to understand how to take advantage of using multi threads. I wrote a simple program that increments the value of i, let's say, 400,000 times using two ways : a single threaded way (0 to 400,000) and a multiple threaded way (in my case, 4 times : 0 to 100,000) with the number of thread equal to Runtime.getRuntime().availableProcessors().
I'm surprised with the results I measured : the single threaded way is decidedly faster, sometimes 3 times faster. Here is my code :
public class Main {
public static int LOOPS = 100000;
private static ExecutorService executor=null;
public static void main(String[] args) throws InterruptedException, ExecutionException {
int procNb = Runtime.getRuntime().availableProcessors();
long startTime;
long endTime;
executor = Executors.newFixedThreadPool(procNb);
ArrayList<Calculation> c = new ArrayList<Calculation>();
for (int i=0;i<procNb;i++){
c.add(new Calculation());
}
// Make parallel computations (4 in my case)
startTime = System.currentTimeMillis();
queryAll(c);
endTime = System.currentTimeMillis();
System.out.println("Computation time using " + procNb + " threads : " + (endTime - startTime) + "ms");
startTime = System.currentTimeMillis();
for (int i =0;i<procNb*LOOPS;i++)
{
}
endTime = System.currentTimeMillis();
System.out.println("Computation time using main thread : " + (endTime - startTime) + "ms");
}
public static List<Integer> queryAll(List<Calculation> queries) throws InterruptedException, ExecutionException {
List<Future<Integer>> futures = executor.invokeAll(queries);
List<Integer> aggregatedResults = new ArrayList<Integer>();
for (Future<Integer> future : futures) {
aggregatedResults.add(future.get());
}
return aggregatedResults;
}
}
class Calculation implements Callable<Integer> {
#Override
public Integer call() {
int i;
for (i=0;i<Main.LOOPS;i++){
}
return i;
}
}
Console :
Computation time using 4 threads : 10ms.
Computation time using main thread : 3ms.
Could anyone explain this ?
An addition probably takes one cpu cycle, so if your cpu runs at 3GHz, that's 0.3 nanoseconds. Do it 400k times and that becomes 120k nanoseconds or 0.1 milliseconds. So your measurement is more affected by the overhead of starting threads, thread switching, JIT compilation etc. than by the operation you are trying to measure.
You also need to account for the compiler optimisations: if you place your empty loop in a method and run that method many times you will notice that it runs in 0 ms after some time,. because the compiler determines that the loop does nothing and optimises it away completely.
I suggest you use a specialised library for micro benchmarking, such as jmh.
See also: How do I write a correct micro-benchmark in Java?

Java on Linux: Measuring elapsed time using System.nanotime() for a thread that blocks

I have a thread that takes an object from an ArrayBlockingQueue() connectionPool. The thread may be blocked if ArrayBlockingQueue() is empty. To measure the time for which the calling thread is blocked, I use the following code:
long start = System.nanoTime();
DataBaseEndPoint dbep = connectionPool.take();
long end = System.nanoTime();
long elapsed = (end - start)/1000000;
Now, my concern is that the unblocked thread may start running on a different processor in a multi-processor machine. In that case, I am not entirely sure if the 'System Timer' used is the same on different processors.
This blog-post (http://www.javacodegeeks.com/2012/02/what-is-behind-systemnanotime.html) suggests that Linux uses a different Time-Stamp counter for each processor (also used for System.nanotime()), which can really mess up the elapsed time calculation in the above example.
The value is read from clock_gettime with CLOCK_MONOTONIC flag Which
uses either TSC or HPET. The only difference with Windows is that
Linux not even trying to sync values of TSC read from different CPUs,
it just returns it as it is. It means that value can leap back and
jump forward with dependency of CPU where it is read.
This link (http://lwn.net/Articles/209101/) however, suggests that TSC is no longer used for high-resolution timers.
... the recently-updated high-resolution timers and dynamic tick patch
set includes a change which disables use of the TSC. It seems that the
high-resolution timers and dynamic tick features are incompatible with
the TSC...
So, the question is, what is used by a Linux machine to return value to System.nanotime() currently? And, is using System.nanotime() safe for measuring elapsed time in the above case (blocked thread starting on another processor). If it isn't safe, what's the alternative?
One thing invaluable about virtual machines (and life in general) is abstraction. The threads' execution time do not differ based on the number of cores; not in Linux, nor in Windows, etc... I hope I am not misunderstanding your question.
(Although I am using currentTimeMillis(), nanotime is the same in a different scale, of course)
Check the following example I crafted:
public class SynchThreads {
public static void main(String[] args) throws InterruptedException {
GreedyTask gtA = new GreedyTask("A");
GreedyTask gtB = new GreedyTask("B");
Thread a = new Thread(gtA);
Thread b = new Thread(gtB);
a.start();
b.start();
a.join();
b.join();
System.out.println(gtA.toString()+" running time: "+gtA.getRunningTime());
System.out.println(gtB.toString()+" running time: "+gtB.getRunningTime());
}
private static class GreedyTask implements Runnable {
private long startedTime, finishedTime, totalRunTime;
private String myName;
public GreedyTask(String pstrName) {
myName = pstrName;
}
public void run() {
try {
startedTime = System.currentTimeMillis();
randomPowerNap(this);
finishedTime = System.currentTimeMillis();
totalRunTime = finishedTime - startedTime;
} catch (Exception e) { System.err.println(e.getMessage()); }
}
public String toString() { return ("Task: " + myName); }
public long getRunningTime() { return this.totalRunTime; }
}
private static synchronized void randomPowerNap(GreedyTask gt) throws InterruptedException {
System.out.println("Executing: "+gt.toString());
long random = Math.round(Math.random()*15000);
System.out.println("Random time for "+gt+" is: "+random);
Thread.sleep(random);
}
}
The following is the output of a run in a 4 cores windows machine:
Executing: Task: A
Random time for Task: A is: 1225
Executing: Task: B
Random time for Task: B is: 4383
Task: A running time: 1226
Task: B running time: 5609 // what's funny about this? this is equal to Btime - Atime
This was run in a 4 cores Linux machine:
Executing: Task: A
Random time for Task: A is: 13577
Executing: Task: B
Random time for Task: B is: 5340
Task: A running time: 13579
Task: B running time: 18920 // same results
Conclusions: B total time adds the time it had to wait while randomPowerNap was blocked by A, hence due to the hardware abstraction of the virtual machine, threads see no difference in their running times since they all run in a 'VIRTUAL BIG CORE', if you know what I meant.
I hope this helped.

start a thread which terminates the process after a specified time

I am executing a program for a network where i have a certain number of tasks execution in loop, it works fine but when there a any flaws occurs due to network problem it got stuck in one of any task. so i want to create a thread which start at the time when control goes in to loop and after some delay it terminate it self with continuing the process.
for example-
for ( /*itearting condition */)
{
//thread start with specified time.
task1;
task2;
task3;
//if any execution delay occur then wait till specified time and then
//continue.
}
Please give me some clue regarding this, a snippets can help me a lot as i need to fix it shortly.
A thread can only be terminated with its cooperation (assuming you want to save the process). With the thread's cooperation, you can terminate it with any termination mechanism it supports. Without its cooperation, it cannot be done. The usual way to do it is to design the thread to sanely handle being interrupted. Then you can have another thread interrupt it if too much time passes.
I think you may need something like this:
import java.util.Date;
public class ThreadTimeTest {
public static void taskMethod(String taskName) {
// Sleeps for a Random amount of time, between 0 to 10 seconds
System.out.println("Starting Task: " + taskName);
try {
int random = (int)(Math.random()*10);
System.out.println("Task Completion Time: " + random + " secs");
Thread.sleep(random * 1000);
System.out.println("Task Complete");
} catch(InterruptedException ex) {
System.out.println("Thread Interrupted due to Time out");
}
}
public static void main(String[] arr) {
for(int i = 1; i <= 10; i++) {
String task = "Task " + i;
final Thread mainThread = Thread.currentThread();
Thread interruptThread = new Thread() {
public void run() {
long startTime = new Date().getTime();
try {
while(!isInterrupted()) {
long now = new Date().getTime();
if(now - startTime > 5000) {
//Its more than 5 secs
mainThread.interrupt();
break;
} else
Thread.sleep(1000);
}
} catch(InterruptedException ex) {}
}
};
interruptThread.start();
taskMethod(task);
interruptThread.interrupt();
}
}
}

Categories