![]() |
AppPerfect Java Profiler |
This tutorial provides instructions on how to use AppPerfect Java Profiler product for detecting monitor contention and possible race conditions in a java application. This tutorial assumes you have successfully downloaded and installed AppPerfect DevTest4J on your machine with the default options.
This document is divided into following sections
Within each section, multiple exercises are listed. All exercises assume you have installed the product in C:\AppPerfect\DevTest folder and will be referred as DEVTEST_HOME henceforth in tutorial. If you have installed the product in some other folder, modify the instructions below appropriately.
For this tutorial, create a java file called 'MonitorContention.java' copy-pasting the
code shown below and compile it.
import java.io.*;
public class MonitorContention
{
private static final int queue_size = 1000;
private Object[] queue = new Object[ queue_size ];
private int head = 0;
private int tail = 0;
public synchronized void enqueue( Object item )
{
head %= queue_size;
queue[++(head)]= item;
this.notify(); // The "this" is there only to
} // improve readability.
public synchronized Object dequeue( )
{
try
{
if( head == tail ) // <=== This is a bug
{
long startTime = System.currentTimeMillis();
System.out.println("waiting...");
this.wait();
System.out.println("waiting... time=" + (System.currentTimeMillis() - startTime)/1000);
}
}
catch( InterruptedException e )
{
// If we get here, we were not actually notified.
// returning null does not indicate that the
// queue is empty, only that the waiting was
// abandoned.
return null;
}
tail %= queue_size;
return queue[++(tail) ];
}
public static void main(String[] args) throws Exception
{
MonitorContention contention = new MonitorContention();
InputStreamReader console = new InputStreamReader(System.in);
Thread.sleep(2000);
createMonitorContentionThread(contention, 8).start();
createMonitorContentionThread(contention, 12).start();
Thread.sleep(5000);
System.out.println("Release ONE");
createReleaseThread(contention, 2).start();
Thread.sleep(9000);
System.out.println("Release TWO");
createReleaseThread(contention, 2 + 8 + 12).start();
System.out.print("Press any key to continue...");
console.read();
console.read();
}
static int count = 0;
public static Thread createMonitorContentionThread(final MonitorContention contention, final int enqueCount)
{
final int th_id = count++;
return new Thread(new Runnable()
{
public void run()
{
try
{
for(int i = 0; i < 2 + (enqueCount/2); ++i)
{
contention.enqueue(new Object());
}
System.out.println("Waiting for 5 sec. [" + th_id + "]");
for(int i = 0; i < enqueCount; ++i)
{
contention.dequeue();
System.out.println("Waiting for 0.1 sec. [" + th_id + "]");
Thread.sleep(100);
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
});
}
public static Thread createReleaseThread(final MonitorContention contention, final int dequeCount)
{
final int th_id = count++;
return new Thread(new Runnable()
{
public void run()
{
try
{
for(int i = 0; i < dequeCount; ++i)
{
contention.enqueue(new Object());
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
});
}
}
Action:
Action:
RaceCondition.class" file.RaceCondition.class"
file. NB:Please follow the steps provided in the "Creating Common Project" section to first create a common project, then proceed further.
Action:
Action:

