Results 1 to 7 of 7
  1. #1
    cuffJ is offline Member
    Join Date
    Aug 2010
    Posts
    2
    Rep Power
    0

    Default Problems using wait() and notifyAll() with locks

    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[i]=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
    {
    while (i<first.length && j<second.length)
    {
    sortStateLock.lock();
    try
    {
    while (isPaused)
    sortStateLock.wait();
    //Methods for merging now shown
    }
    finally
    {
    sortStateLock.unlock();
    }
    pause(2);
    }
    repaint();
    }
    public void paint(Graphics g)
    {
    sortStateLock.lock();
    try
    {
    try
    {
    while (isPaused)
    sortStateLock.wait();
    }
    catch(InterruptedException e)
    {
    System.out.println("Problem in painting");
    e.printStackTrace();
    }
    //Methods for painting lines not shown
    }
    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;
    }

  2. #2
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,572
    Rep Power
    25

    Default

    Please edit you posted code and add code tags to preserve indentations.

    Have you tried debugging your code by adding println() to show where/what the code is doing and how variables are changing?


    Your code doesn't compile:
    Java Code:
    Running: D:\Java\jdk1.6.0_02\bin\javac.exe -Xlint -g -deprecation -classpath D:\JavaDevelopment\;.;..\..\..\..\. MergePanel.java
    
    MergePanel.java:141: cannot find symbol
    symbol  : variable i
    location: class MergePanel
    while (i<first.length && j<second.length)
           ^
    MergePanel.java:141: cannot find symbol
    symbol  : variable first
    location: class MergePanel
    while (i<first.length && j<second.length)
             ^
    MergePanel.java:141: cannot find symbol
    symbol  : variable j
    location: class MergePanel
    while (i<first.length && j<second.length)
                             ^
    MergePanel.java:141: cannot find symbol
    symbol  : variable second
    location: class MergePanel
    while (i<first.length && j<second.length)
                               ^
    MergePanel.java:35: warning: [serial] serializable class MergePanel has no definition of serialVersionUID
    public class MergePanel extends JPanel {
           ^
    4 errors
    1 warning
    
    3 error(s)
    Last edited by Norm; 08-16-2010 at 11:32 PM.

  3. #3
    Maxideon is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default

    If you are going to use Lock objects for your synchronization purposes, you should use Condition objects for your wait() and notifyAll() purposes. As it is, you are calling wait() directly on your ReentrantLock. That's not how it works.

  4. #4
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    20

    Default

    And also please use code tags when you are posting again. Unformated codes are really hard to read.

  5. #5
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    20

    Default

    Quote Originally Posted by Norm View Post
    Please edit you posted code and add code tags to preserve indentations.

    Have you tried debugging your code by adding println() to show where/what the code is doing and how variables are changing?

    Your code doesn't compile:
    yeah, seems to me this code is not written by the OP or may be this is a part of an assignment. :rolleyes:

  6. #6
    JosAH's Avatar
    JosAH is online now Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,658
    Blog Entries
    7
    Rep Power
    21

    Default

    Maxideon is right: the OP should read the API documentation for ReentrantLock objects and Condition variables.

    kind regards,

    Jos

  7. #7
    cuffJ is offline Member
    Join Date
    Aug 2010
    Posts
    2
    Rep Power
    0

    Default

    Ok, thanks everyone. Really sorry about the indentations; i'm new to these forums. The condition tip helped alot. Thanks again.

Similar Threads

  1. InterruptedException and Locks
    By JavaJuJitZu in forum Threads and Synchronization
    Replies: 3
    Last Post: 02-19-2010, 02:47 AM
  2. wait() and notify() problems
    By greyradio in forum Threads and Synchronization
    Replies: 1
    Last Post: 08-03-2009, 03:36 AM
  3. about wait() and notifyALL
    By denis in forum Threads and Synchronization
    Replies: 13
    Last Post: 04-22-2009, 08:28 AM
  4. Thread Safe Methods / Locks
    By mrhyman in forum Threads and Synchronization
    Replies: 16
    Last Post: 10-24-2008, 09:57 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •