Deadlocking threads

Discussion in 'Java' started by Sunitha Kumar, Jul 8, 2003.

  1. Hi,

    I've implemented a Fixed Queue that contains even and odd Integers with one
    each EvenProducer, EvenConsumer. OddProducer, OddConsumer threads, all
    capable of producing and consuming ten even or odd Integers each. My problem
    is that my threads stop consuming after a certain point (the 7th iteration,
    according to my debugger) and I can't figure out why. (I've used different
    sleep times, synchronized all methods to no avail.)

    I've attached my code below:
    /**
    * EvenConsumer
    * @
    */
    public class EvenConsumer extends Thread
    {
    private FixedQueue queue;
    private int number;
    private int workCount;
    public EvenConsumer(FixedQueue q, int i)
    {
    this.queue= q;
    this.number= i;
    }
    public void run()
    {
    try
    {
    for (int i= 0; i < 10; i++)
    {
    Integer value= queue.evenDequeue();
    System.out.println(
    "Even Consumer #" + this.number + " removed " + value);
    System.out.println(queue.toString());
    trackWorkPerformance(i);
    sleep((int) (Math.random() * 20));
    }
    generatePerformanceReport(this.workCount);
    }
    catch (InterruptedException e)
    {
    }
    }
    private void trackWorkPerformance(int i)
    {
    workCount= i + 1;
    }
    private void generatePerformanceReport(int workCount)
    {
    System.out.println(
    "Even Consumer #"
    + this.number
    + " has been working "
    + workCount
    + " times.");
    }
    }

    /**
    * EvenProducer
    * @ Places randomly generated even Integer objects into
    * the rear of a FixedQueue.
    */
    public class EvenProducer extends Thread
    {
    private FixedQueue queue;
    private int number;
    private int workCount;
    public EvenProducer(FixedQueue q, int i)
    {
    this.queue= q;
    this.number= i;
    }
    public void run()
    {
    try
    {
    for (int i= 0; i < 10; i++)
    {
    int value= Random.nextEvenInt();
    queue.evenEnqueue(new Integer(value));
    //System.out.println(value);
    System.out.println(
    "Even Producer #" + this.number + " put " + value);
    System.out.println(queue.toString());
    trackWorkPerformance(i);
    sleep((int) (Math.random() * 30));
    }
    generatePerformanceReport(this.workCount);
    }
    catch (InterruptedException e)
    {
    }
    }
    private void trackWorkPerformance(int i)
    {
    workCount= i + 1;
    }
    private void generatePerformanceReport(int workCount)
    {
    System.out.println(
    "Even Producer #"
    + this.number
    + " has been working "
    + workCount
    + " times.");
    }
    }

    /**
    * OddConsumer
    * @
    */
    public class OddConsumer extends Thread
    {
    private FixedQueue queue;
    private int number;
    private int workCount;
    public OddConsumer(FixedQueue q, int i)
    {
    this.queue= q;
    this.number= i;
    }
    public void run()
    {
    try
    {
    for (int i= 0; i < 10; i++)
    {
    Integer value= queue.oddDequeue();
    System.out.println(
    "Odd Consumer #" + this.number + " removed " + value);
    System.out.println(queue.toString());
    trackWorkPerformance(i);
    sleep((int) (Math.random() * 10));
    }
    generatePerformanceReport(this.workCount);
    }
    catch (InterruptedException e)
    {
    }
    }
    private void trackWorkPerformance(int i)
    {
    workCount= i + 1;
    }
    private void generatePerformanceReport(int workCount)
    {
    System.out.println(
    "Odd Consumer #"
    + this.number
    + " has been working "
    + workCount
    + " times.");
    }
    }

    /**
    * OddProducer
    * @
    */
    public class OddProducer extends Thread
    {
    private FixedQueue queue;
    private int workCount;
    private int number;
    public OddProducer(FixedQueue q, int i)
    {
    this.queue= q;
    this.number= i;
    }
    public void run()
    {
    try
    {
    for (int i= 0; i < 10; i++)
    {
    int value= Random.nextOddInt();
    queue.oddEnqueue(new Integer(value));
    //System.out.println(value);
    System.out.println(
    "OddProducer #" + this.number + " put " + value);
    System.out.println(queue.toString());
    trackWorkPerformance(i);
    sleep((int) (Math.random() * 10));
    }
    generatePerformanceReport(this.workCount);
    }
    catch (InterruptedException e)
    {
    }
    }
    private void trackWorkPerformance(int i)
    {
    workCount = i+1;
    }

    private void generatePerformanceReport(int workCount)
    {
    System.out.println(
    "Odd Producer #"
    + this.number
    + " has been working "
    + workCount
    + " times.");
    }
    }

    /**
    * FixedQueue
    * @
    */
    public class FixedQueue
    {
    private static FixedQueue singleton= new FixedQueue();
    private boolean evenAvailable= false;
    private Integer num, value;
    private boolean oddAvailable= false;
    private final LinkedList queue= new LinkedList();
    private int queueSize= 5;
    public synchronized Integer evenDequeue() throws InterruptedException
    {
    while ((evenAvailable == false) || (isEmpty()) || (isOdd()))
    {
    wait();
    }
    value= (Integer) queue.removeFirst();
    evenAvailable= false;
    notifyAll();
    return value;
    }
    public synchronized void evenEnqueue(Integer i) throws
    InterruptedException
    {
    while (isFull())
    {
    wait();
    }
    queue.addLast(i);
    evenAvailable= true;
    notifyAll();
    }
    /**
    * @param num
    * @return
    */
    private synchronized boolean isEven()
    {
    Integer value= (Integer) queue.get(0);
    return value.intValue() % 2 == 0;
    }
    private synchronized boolean isFull()
    {
    return (queueSize == queue.size());
    }
    public synchronized boolean isEmpty()
    {
    return (queue.size() == 0);
    }
    public synchronized boolean isOdd()
    {
    Integer value= (Integer) queue.get(0);
    return value.intValue() % 2 == 1;
    }
    public synchronized Integer oddDequeue()
    {
    while ((oddAvailable == false) || (isEmpty()) || (isEven()))
    {
    try
    {
    wait();
    }
    catch (InterruptedException e)
    {
    }
    }
    value= (Integer) queue.removeFirst();
    oddAvailable= false;
    notifyAll();
    return value;
    }
    public synchronized void oddEnqueue(Integer i)
    {
    while (isFull())
    {
    try
    {
    wait();
    }
    catch (InterruptedException e)
    {
    }
    }
    queue.addLast(i);
    oddAvailable= true;
    notifyAll();
    }
    public synchronized String toString()
    {
    return queue.toString();
    }
    }

    /**
    * Random
    * @ Generates random odd and even int numbers.
    */
    public class Random
    {
    private static final java.util.Random RAND= new java.util.Random();
    private static final int EVEN_MASK= -2;
    private static final int ODD_MASK= 1;
    public static synchronized int nextEvenInt()
    {
    return RAND.nextInt() & EVEN_MASK;
    }
    public static synchronized int nextOddInt()
    {
    return RAND.nextInt() | ODD_MASK;
    }
    }

    /**
    * QueueException
    * @
    */
    public class QueueException extends Exception
    {
    /**
    *
    */
    public QueueException()
    {
    super();

    }
    }

    Any help would be appreciated!

    Thanks,
    Sunitha
     
    Sunitha Kumar, Jul 8, 2003
    #1
    1. Advertising

  2. Sunitha Kumar

    Jon Skeet Guest

    Sunitha Kumar <> wrote:
    > I've implemented a Fixed Queue that contains even and odd Integers with one
    > each EvenProducer, EvenConsumer. OddProducer, OddConsumer threads, all
    > capable of producing and consuming ten even or odd Integers each. My problem
    > is that my threads stop consuming after a certain point (the 7th iteration,
    > according to my debugger) and I can't figure out why. (I've used different
    > sleep times, synchronized all methods to no avail.)


    I haven't checked, but I *suspect* the problem is with your
    evenAvailable/oddAvailable flags - there's no need for them given the
    isOdd/isEven check, and you reset them after fetching an even number -
    which means if there are two even numbers in a row in the queue, you'll
    stop consuming until the next even number is added to the far end.

    That's just a guess after reading through the code very briefly though.

    I would personally have a design with two separate queues - much
    simpler.

    --
    Jon Skeet - <>
    http://www.pobox.com/~skeet/
    If replying to the group, please do not mail me too
     
    Jon Skeet, Jul 8, 2003
    #2
    1. Advertising

  3. On Tue, 08 Jul 2003 01:16:39 -0700, Sunitha Kumar wrote:

    > Hi,
    >
    > I've implemented a Fixed Queue that contains even and odd Integers with one
    > each EvenProducer, EvenConsumer. OddProducer, OddConsumer threads, all
    > capable of producing and consuming ten even or odd Integers each. My problem
    > is that my threads stop consuming after a certain point (the 7th iteration,
    > according to my debugger) and I can't figure out why. (I've used different
    > sleep times, synchronized all methods to no avail.)
    >


    See my answer in another group.

    Steve
     
    Steve Horsley, Jul 8, 2003
    #3
  4. Sunitha Kumar

    Jon Skeet Guest

    Sunitha Kumar <> wrote:
    > Jon, I commented out the evenAvailable/oddAvailable flags to test your
    > theory - the threads still locked, unfortunately.
    >
    > Thanks though, you're right of course - I overlooked the fact that by
    > testing for isOdd/isEven, the flags for oddAvailable/evenAvailable become
    > redundant.


    Right. In that case, could you post your complete app (so we can
    actually run it) after the flags have been removed (and possibly taking
    into account Steve's point about using Runnable). If it's quite large,
    it might be worth putting it in a zip file and putting it on a web site
    somewhere. If you want to mail it to me, feel free.

    > > I would personally have a design with two separate queues - much
    > > simpler.

    >
    > Right, I wish I could too, but the single fixed queue is a requirement for
    > this assignment.


    Does it have to be a single fixed queue in implementation, or only in
    interface? In other words, is there anything to stop you from actually
    having two "hidden" queues, and forwarding on the produce/consume
    requests to them?

    --
    Jon Skeet - <>
    http://www.pobox.com/~skeet/
    If replying to the group, please do not mail me too
     
    Jon Skeet, Jul 8, 2003
    #4
  5. "Steve Horsley" <_SPAM.net> wrote in message
    news:p_SPAM.net...
    > See my answer in another group.


    Thanks Steve, I've replied to your post in comp.lang.java.help :)
     
    Sunitha Kumar, Jul 8, 2003
    #5
  6. Sunitha Kumar

    Jon Skeet Guest

    [Also replied via email]

    Sunitha Kumar <> wrote:

    <snip>

    > Thanks Jon, I have mailed it to you at (in a zipped file, of
    > course).
    >
    > > Does it have to be a single fixed queue in implementation, or only in
    > > interface? In other words, is there anything to stop you from actually
    > > having two "hidden" queues, and forwarding on the produce/consume
    > > requests to them?


    After all that, the problem (aside from the flags, which I'm sure were
    also duff) is in testing for an odd number. You can't use if (x%2==1)
    to test for oddity when x can be negative, as (say) -3%2 = -1, not 1.
    The easiest change is to use &1 instead of %2 in this case.

    --
    Jon Skeet - <>
    http://www.pobox.com/~skeet/
    If replying to the group, please do not mail me too
     
    Jon Skeet, Jul 8, 2003
    #6
  7. "Jon Skeet" <> wrote in message
    news:...
    > [Also replied via email]


    Thanks for your help - modifying the test for oddity solved the deadlock.

    > After all that, the problem (aside from the flags, which I'm sure were
    > also duff) is in testing for an odd number. You can't use if (x%2==1)
    > to test for oddity when x can be negative, as (say) -3%2 = -1, not 1.
    > The easiest change is to use &1 instead of %2 in this case.


    Or even better for clarity: if (x%2!=0) to test for oddity.

    :)
     
    Sunitha Kumar, Jul 8, 2003
    #7
    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. =?Utf-8?B?TWFya0BXRkk=?=

    global sql connection string and deadlocking error

    =?Utf-8?B?TWFya0BXRkk=?=, Nov 12, 2003, in forum: ASP .Net
    Replies:
    4
    Views:
    874
    Steve C. Orr [MVP, MCSD]
    Nov 12, 2003
  2. yoda
    Replies:
    2
    Views:
    462
    =?utf-8?Q?Bj=C3=B6rn_Lindstr=C3=B6m?=
    Aug 1, 2005
  3. =?Utf-8?B?SnVhbiBEZW50?=

    ASP.NET using COM+ is deadlocking

    =?Utf-8?B?SnVhbiBEZW50?=, Sep 12, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    450
    Walter Wang [MSFT]
    Sep 13, 2006
  4. threads without threads

    , Aug 27, 2004, in forum: C Programming
    Replies:
    4
    Views:
    432
    William Ahern
    Aug 27, 2004
  5. Pedro Pinto

    Java Threads - Get running threads

    Pedro Pinto, Apr 8, 2008, in forum: Java
    Replies:
    2
    Views:
    1,483
    Arne Vajhøj
    Apr 9, 2008
Loading...

Share This Page