1,105,633 Community Members

Multithreading; completely lost...

Member Avatar
crownedzero
Light Poster
38 posts since Sep 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Still playing with multi-threading and Prod-Con, at this point I've been at this for days. Would love some help debugging; thanks in advance.

http://pastebin.com/jhHB9kTY - Main
http://pastebin.com/BZSspf3x - Consumer
http://pastebin.com/ndzAADJz - Producer
http://pastebin.com/p7YdzH1D - Product
http://pastebin.com/rxs3WzDT - Message
http://pastebin.com/JR5ywgz1 - Utiliy

2 Producers, 4 Consumers

Essentially Producers push a message onto the queue, message consists of a prod obj, date obj, and region string.
This sharedQueue[0] is checked by each Consumer for thier region in which case they store it in a local variable and append it to internal lists.

Again thanks for the help.

Member Avatar
NormR1
Posting Sage
7,723 posts since Jun 2010
Reputation Points: 563 [?]
Q&As Helped to Solve: 793 [?]
Skill Endorsements: 16 [?]
Team Colleague
 
0
 

Can you make a small, simple, single program file that shows the problem you are working on? Or merge the six files into one file and post that.

Member Avatar
crownedzero
Light Poster
38 posts since Sep 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

The two important classes; iirc the error is about IllegalMonitorException; the Producers pop onto the queue , the Consumers don't pull anything.

public class Producer implements Runnable {

    protected final static List<Message> sharedQueue = new ArrayList<>();
    protected final int MAX_SIZE = 10;

    @Override
    public void run() {
        while (true) {
            synchronized (sharedQueue) {
                while (sharedQueue.size() == MAX_SIZE) {
                    try {
                        sharedQueue.wait();
                    } catch (InterruptedException e) {
                    }
                }
                sharedQueue.add(new Message(Utility.getRandomProduct(), new Date(), Utility.regionLookup(Utility.getState())));
                System.out.println(Thread.currentThread().getName() + " adding. Queue size: " + sharedQueue.size());
            }
        }
    }

    public static Message messageConsume(String region) {
        synchronized(sharedQueue) {
        while (sharedQueue.isEmpty()) {
            try {
                sharedQueue.wait();
            } catch (InterruptedException e) {
            }
        }
        if (sharedQueue.get(0).getRegion().equalsIgnoreCase(region)) {
            Message tempMessage = sharedQueue.get(0);
            sharedQueue.remove(0);
            return tempMessage;
        } else {
            return null;
        }
        }
    }
}

public class Consumer implements Runnable {

    private List<Message> consumerList = new ArrayList<>();

    @Override
    public void run() {
        while (true) {
            try {
                Message tempMessage = Producer.messageConsume(Thread.currentThread().getName());
                if (tempMessage.getRegion().equalsIgnoreCase(Thread.currentThread().getName())) {
                    consumerList.add(tempMessage);
                }  Thread.sleep(500);
            } catch (InterruptedException ex) {
                Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
Member Avatar
NormR1
Posting Sage
7,723 posts since Jun 2010
Reputation Points: 563 [?]
Q&As Helped to Solve: 793 [?]
Skill Endorsements: 16 [?]
Team Colleague
 
0
 

How do you test the posted code? I don't see a main() method?

Can you post the full text of the error message? I can not find: IllegalMonitorException

Member Avatar
Taywin
Posting Maven
2,632 posts since Apr 2010
Reputation Points: 134 [?]
Q&As Helped to Solve: 378 [?]
Skill Endorsements: 17 [?]
 
1
 

In Producer class inside messageConsume() method, did a call from consumer go through the loop down to the checking for region? If so, did it actually get through inside the checking region if-condition? Try to print out each line of your process to pin point where exactly is wrong.

Anyway, I see you use wait() method, but who is going to wake the thread up after the wait()? Where are you putting your notify()? A thread can't simply wake up after being wait(). The same goes to pushing message onto the queue. Once the queue is full, who is going to wake the thread up to keep pushing again?

public static Message messageConsume(String region) {
  synchronized(sharedQueue) {
    while (sharedQueue.isEmpty()) {
      try {
        sharedQueue.wait();  // Who is going to notify this thread???
      } catch (InterruptedException e) { }
    }
    System.out.println("Queue size: "+sharedQueue.size());
    if (sharedQueue.get(0).getRegion().equalsIgnoreCase(region)) {
      Message tempMessage = sharedQueue.remove(0);
      System.out.println("Removed: "+tmpMessage);
      //sharedQueue.remove(0);   // use remove() right away, don't need this
      System.out.println("Queue size after removed: "+sharedQueue.size());
      return tempMessage;
    } else {
      return null;
    }
  }
}

Personally, I would keep the synchronized block as small as I could. Also, I would keep an infinite loop out of the block (the current while loop). I would instead check if an item is returned after each loop; otherwise, I will wait.

Member Avatar
crownedzero
Light Poster
38 posts since Sep 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Main consists of just instantiating and starting the threads nothing else atm.

Taywin, thanks I made a few changes and I'm no longer getting the IllegalMonitor Exception for the time being; instead a NUllPointer which I believe happens in the messageConsume; I'll check it out and post back. Thanks,

Member Avatar
crownedzero
Light Poster
38 posts since Sep 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Smooth as butter, thanks!

Question Answered as of 1 Year Ago by NormR1 and Taywin
You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: