views:

108

answers:

2

For some reason, the output of this:

 public void msgNeedParts() {
    // Blabla...
    System.out.println(name + ": Try to print 'tasks'...");
    synchronized(tasks) {
        System.out.println(name + ": Tasks--" + tasks);
        System.out.println(name + ": Did I manage to print it?");
        tasks.add(new BinToDump(feeder, binNum));
    }
    stateChanged();
 }

Just prints out "GantryAgent: Try to print 'tasks'..." but not any of the following messages. I'm guessing the thread somehow 'gets stuck' when trying to access the synchronized list 'tasks', but I don't know why this is happening.

'tasks' was declared and initialized like this:

private List<BinToDump> tasks = 
    Collections.synchronizedList(new ArrayList<BinToDump>());

Can anybody point out what I'm missing?

Ah! I suspect I may have a culprit:

    /* If nothing left to do, return to original position. */

    synchronized (tasks) {

        if (tasks.isEmpty()) {

            doReturnToOriginalPos();

        }

    }

In my scheduler (this is an agent design), I check to see if 'tasks' is empty, then I call doReturnToOriginalPos(). Maybe this is just happening over and over so fast that other methods don't get a chance to modify it?

That was indeed the problem! It kept getting called so fast in my scheduler that nothing else could access 'tasks'. Thanks all for the help!

+2  A: 

Is it possible that another thread is holding a synchronization lock against tasks?

RickNZ
Aha! Thanks for pointing that out--I checked with: System.out.println(Thread.holdsLock(tasks)); ...And it returned false.
FallSe7en
@FallSe7en: That method only checks if the *current* thread holds the lock (which you already knew it doesn't since it blocks forever on the acquire :-)). If you're running with Java 6, fire up VisualVM or JConsole, connect to your process and you'll be able to see which thread is holding the lock (and its stacktrace).
Andrzej Doyle
Just `jstack` will do.
Tom Hawtin - tackline
+6  A: 

Something has a lock on tasks. Depending on what sort of application this is, you should be able to get a full stack dump of the system, but the method varies. For example, I think CTRL-Break on most windows-based appservers will do this, and I think sending a SIGQUIT on linux will do the same.

Once you get a stack dump, you can look through it to try and find out which other thread has a lock on that object.

You can also use VisualVM to get a stack dump, for the same end goal:

You can use Java VisualVM to take a thread dump (stack trace) while a local application is running. Taking a thread dump does not stop the application. When you print the thread dump you get a printout of the thread stack that includes thread states for the Java threads.

When you print a thread dump in Java VisualVM, the tool prints a stack trace of the active threads of the application. Using Java VisualVM to take a thread dump can be very convenient in cases where you do not have a command-line console for the application. You can use a stack trace to help diagnose a number of issues such as deadlocks or when an application hangs.

skaffman
Sometimes JVisualVM is an absolute life-saver.
Software Monkey