4 Replies Latest reply: Jul 20, 2009 1:39 PM by 807588 RSS

    Multithreading issues in Linux

    807588
      I have a GUI program I'm helping to develop. It has several graphs, drawn using JOGL, a table of data, and a control window. Each graph is a separate entity, and everything is controlled in sync with the control window. So, we use the observer pattern (all windows observe the control window, which controls the time). In order for the control window to continue updating the time regardless of how many frames per second the graphs can generate, the time is incremented in it's own thread, as follows :
      Thread th = new Thread(new Runnable() {
                      //this will be running in the background the whole simulation to
                      //keep track of the current time
                      public void run() {
                          long time = System.currentTimeMillis();
                          while(true) {
                              if(!pauseClicked){
                                  int speedVal = 100 - speedSlider.getValue();
                                  int incrementTime = 50 + (int)(speedVal*4.5);
                                  if (System.currentTimeMillis() >= time +
                                          incrementTime &&
                                          timeSlider.getValue() < timeSlider.getMaximum()) {
                                      timeSlider.setValue(timeSlider.getValue() + 1);
                                      time = System.currentTimeMillis();
                                      notifyListeners();
                                  }
                                  
                              }
                          }
                      }
                  });
      So, basically, this thread continuously loops, checking the time against the current animation speed. If it finds it should increase the animation time, then it does, and it notifies all listeners (the animations) that the time has changed. This notification simply sets a boolean in each animation, telling it that the time has changed. Each animation will handle this news in its own way, and since it is running in a separate thread, has no affect on the time thread.

      Or, rather, it shouldn't.

      So, if every thread is started, everything works fine. When running this application in Windows, this works perfectly every single time. However, in Linux, it will randomly freeze at some point. Out of 10 runs, I was able to get the application to run correctly, only twice. Usually it will start some of the threads, and then freeze everything when trying to make another thread. Other times, it will create every thread, run the timer thread a single time, and then freeze everything. There is no error, no exception. It just freezes, as if it's in a busy waiting state.
      I traced the program the best that I could and found that usually it was freezing at the java.awt.Component.getTreeLock() method, never returning from it. But I don't believe it was freezing there everytime, only the times when it did not create every thread.

      I would really appreciate any ideas you may have. We are running 64-bit Gentoo, with the 32-bit JVM. We also tested it with the 64-bit JVM with no luck. And Java 1.6.07.

      Thanks in advance for any feedback.
        • 1. Re: Multithreading issues in Linux
          807588
          I don't really understand any of this, but the first thing I'd do if I had a program that hangs would be to hit Ctrl-\ (YMMV) to get thread stack traces. See if there are any deadlocks reported, and see where each thread is sleeping / buzzing.
          • 2. Re: Multithreading issues in Linux
            807588
            Ctrl-\? What program do you use for viewing thread stack traces? Does the Ctrl-\ command you use launch a program in Linux, or is it something in an IDE? If it is a program in Linux, do you know how to launch it from command line? Ctrl-\ does nothing for me.
            • 3. Re: Multithreading issues in Linux
              807588
              SIGQUIT is traditionally bound to Ctrl-\. When running a program in a command interpreter window, Ctrl-\ delivers SIGQUIT to the process, so it works when you start "java YourProgram" in a command interpreter prompt and hit Ctrl-\ to the command interpreter window while the program is running. The Sun JVM gives thread stack traces to stdout when it receives SIGQUIT. Use "stty -a" to see your key bindings.

              If Ctrl-\ doesn't do it for you, you may be able to get stack traces with "kill -QUIT +processid+" or "jstack -l +processid+" (jstack comes with the newest JDKs; "-l" makes it give lock information.)
              • 4. Re: Multithreading issues in Linux
                807588
                That worked great, thanks!
                Turned out the deadlock was in AWT. I was trying to draw two different windows from two separate threads, and apparently, that's not safe. I was able to work around it and create all the windows in the main thread.
                I'm not sure if that's a bug in the Linux JVM or a bug in Linux, or what. But, I'm just glad I was able to get it to work in Linux. Windows is so freaking slow.

                Thanks alot, sjasja!