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

Discussion in 'Java' started by cuffJ, Aug 16, 2010.

  1. cuffJ

    cuffJ

    Joined:
    Aug 15, 2010
    Messages:
    2
    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;
    }
    cuffJ, Aug 16, 2010
    #1
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fuzzyman
    Replies:
    3
    Views:
    486
    Andrew MacIntyre
    Dec 5, 2003
  2. Robert Brewer
    Replies:
    0
    Views:
    485
    Robert Brewer
    Dec 5, 2003
  3. Vera
    Replies:
    5
    Views:
    843
    blmblm@myrealbox.com
    Oct 13, 2006
  4. Bryan
    Replies:
    12
    Views:
    698
    Thomas Hawtin
    Dec 19, 2006
  5. Danny
    Replies:
    18
    Views:
    811
    Daniel Pitts
    Dec 15, 2008
Loading...

Share This Page