Problems with using wait() and notifyall() with lock objects

Joined
Aug 15, 2010
Messages
2
Reaction score
0
Hi,

I'm trying to create a merge sort program that animates a merge sort using threads, with the ability to pause when a button is clicked in the overlying JFrame. The merge sort animation works when the button is not used, but when it is pressed I get an IllegalMonitorStateException, and the program crashes. I understand that this occurs when the lock is not owned, however all my calls to wait() or notifyAll() occur within a lock. If someone could help me out, I know there's a lot of code, but most of it is just managing the sort, and I just need help with wait() problem. I think it has something to do with the fact that I'm calling wait() in so many different methods, but I'm not sure. pauseActions triggers waits, resumeActions calls notifyAll();

Thanks!

/**
* A JPanel performing a merge sort using Threads.
* @param currElement1 One of the 2 current elements being inspected.
* @param currElement2 One of the 2 current elements being inspected.
* @param f Current range being.
* @param t Current range end.
* @param lineSpacing Spacing between Lines
* @param lines Array of heights
* @param sortStateLock Lock to control thread synchronization.
* @param ARRAY_LENGTH Length of Array.
* @param DELAY Pause for each element inspected.
* @author Owner
*
*/
public class MergePanel extends JPanel
{
public MergePanel()
{
sortStateLock=new ReentrantLock();
}
/**
* Initiates random arrays and begins threads.
*/
public void initiate()
{
isPaused=false;
f=0;
t=0;
currElement1=0;
currElement2=0;
lineSpacing=this.getWidth()/ARRAY_LENGTH;
//Fills array Randomly
Random generator=new Random();
lines=new int[ARRAY_LENGTH];
for (int i=0; i<lines.length; i++)
{
lines=generator.nextInt(100);
}
try
{
MyRunnable r=new MyRunnable(0,lines.length-1);
Thread t=new Thread(r);
t.start();
t.join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Arrays.toString(lines));
}
/**
* Class used to create spawned threads.
* @author Owner
*
*/
class MyRunnable implements Runnable
{
private int from;
private int to;
MyRunnable(int f, int t)
{
from=f;
to=t;
}
public void run()
{
try
{
mergeSort(from,to);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
/**
* Divides array up continuously until the array size is 1, spawning new thread for each division.
* At the end, merge is called, merging spawned arrays after they have died (join command).
* @param from Begin of array range being inspected
* @param to End of array range being inspected.
* @throws InterruptedException
*/
public void mergeSort(int from, int to) throws InterruptedException
{
if (to==from) return;
int mid=0;
sortStateLock.lock();
try
{
while (isPaused)
sortStateLock.wait();
//System.out.println(from+" "+to);
mid=(from+to)/2;
}
finally
{
sortStateLock.unlock();
}
if (!isPaused)
{
MyRunnable r1=new MyRunnable(from,mid);
MyRunnable r2=new MyRunnable(mid+1,to);
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
t1.start();
t2.start();
t1.join();
t2.join();
merge(from, mid, to);
}

}
/**
* Merges array sections from to mid and mid+1 to to, pausing after each element inspected in merge
* operation to repaint.
* @param from Beginning of first range.
* @param mid End of first range and beginning of second range.
* @param to End of second range.
* @throws InterruptedException
*/
public void merge(int from, int mid, int to) throws InterruptedException
{
int[] first=new int[mid-from+1];
int[] second=new int[to-mid];
int[] compiled=new int[to-from+1];
System.arraycopy(lines, from, first, 0, mid-from+1);
System.arraycopy(lines,mid+1,second,0,to-mid);
int i=0;
int j=0;
int total=0;
while (i<first.length && j<second.length)
{
sortStateLock.lock();
try
{
while (isPaused)
sortStateLock.wait();
currElement1=i+from;
currElement2=j+mid+1;
if (first<second[j])
{
compiled[total]=first;
i++;
}
else
{
compiled[total]=second[j];
j++;
}
total++;
}
finally
{
sortStateLock.unlock();
}
pause(2);
}
System.arraycopy(first,i,compiled,total,first.leng th-i);
System.arraycopy(second,j,compiled,total,second.le ngth-j);
System.arraycopy(compiled,0,lines,from,compiled.le ngth);
repaint();
f=from;
t=to;
}
public void paint(Graphics g)
{
sortStateLock.lock();
try
{
try
{
while (isPaused)
sortStateLock.wait();
}
catch(InterruptedException e)
{
System.out.println("Problem in painting");
e.printStackTrace();
}
Graphics2D g2=(Graphics2D) g;
g2.clearRect(0,0,this.getWidth(),this.getHeight()) ;
for (int i=0; i<f; i++)
{
if (i!=currElement1 && i!=currElement2)
g2.draw(new Line2D.Double(lineSpacing*i,0,lineSpacing*i,lines));
}
g2.setColor(Color.RED);
for (int i=f; i<=t; i++)
{
if (i!=currElement1 && i!=currElement2)
g2.draw(new Line2D.Double(lineSpacing*i,0,lineSpacing*i,lines));;
}
g2.setColor(Color.BLACK);
for (int i=t+1; i<lines.length; i++)
{
if (i!=currElement1 && i!=currElement2)
g2.draw(new Line2D.Double(lineSpacing*i,0,lineSpacing*i,lines));
}
g2.setColor(Color.GREEN);
g2.draw(new Line2D.Double(lineSpacing*currElement1,0,lineSpaci ng*currElement1,lines[currElement1]));
g2.draw(new Line2D.Double(lineSpacing*currElement2,0,lineSpaci ng*currElement2,lines[currElement2]));
}
finally
{
sortStateLock.unlock();
}
}
/**
* Repaints and pauses to see efficiency of algorithm when compared with others.
* @param steps Number of steps to pause for.
* @throws InterruptedException
*/
public void pause(int steps) throws InterruptedException
{
repaint();
Thread.sleep(DELAY*steps);
}
public boolean isPaused()
{
return isPaused;
}
public void pauseActions()
{
sortStateLock.lock();
try
{
isPaused=true;
}
finally
{
sortStateLock.unlock();
}
}
public void resumeActions()
{
sortStateLock.lock();
try
{
sortStateLock.notifyAll();
isPaused=false;
}
finally
{
sortStateLock.unlock();
}
}
private boolean isPaused;
private int f;
private int t;
private int currElement1;
private int currElement2;
private int lineSpacing;
private static final int ARRAY_LENGTH=100;
private static final int DELAY=100;
private Lock sortStateLock;
private int[] lines;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,056
Messages
2,570,441
Members
47,119
Latest member
NoeliaIrby

Latest Threads

Top