Worker threads seem to affect gui processing

Discussion in 'Java' started by anthony.jayasekera@gmail.com, Sep 1, 2005.

  1. Guest

    I am trying to diagnose some problems with a WaitDialog implementation,
    i.e. a dialog which is displayed whilst a long running process (LRP)
    runs.
    I have pared down the code to a bare minimum for debugging purposes
    (this code is attached to the end of this post).
    The WaitDialog simply an indeterminate progress bar (one which moves up
    and down Night ider style).
    The main method of this code simply launches the wait dialog and then
    runs a method, doWork(), which runs the LRP in a **NEW THREAD**.
    If both the dialog and the method call are launched/invoked in the
    EventDispatchThread using invokeLater() the progress bar motion is
    sluggish.
    This does not make sense to me since the LRP running in doWork() is
    launched in a new thread.
    Furthermore if the code in the LRP is changed to periodically
    relinquish the cpu (using Object.wait(int ms)) the problem goes away.
    I cannot rationalise this behaviour since my understanding is that if
    the LRP is running in a separate thread it should have no noticeable
    affect on work done in other threads.
    I have tried running on JRE 1.4.2, 1.5 on Win2K and WinXP.

    Any ideas would be greatly appreciated.

    Code follows:

    import java.awt.*;
    import java.util.Date;
    import javax.swing.*;
    public class WaitDialog extends JDialog {

    JProgressBar jProgressBar1 = new JProgressBar();

    public WaitDialog(Frame owner, String title) {
    super(owner, title, true);
    _construct();
    }
    private void _construct() {
    JPanel panel = new JPanel();
    panel.setLayout(new GridBagLayout());
    jProgressBar1.setIndeterminate(true);
    panel.setBorder(BorderFactory.createEtchedBorder());
    panel.add(jProgressBar1, new GridBagConstraints(0, 1, 2, 1, 0.0, 0.0,
    GridBagConstraints.SOUTH,GridBagConstraints.BOTH, new Insets(0, 10, 5,
    10), 140, 0));
    setContentPane(panel);
    }

    public static void main(String args[]) {
    final JFrame frame = new JFrame();
    final WaitDialog wd = new WaitDialog(frame, "Waiting...");
    wd.pack();
    SwingUtilities.invokeLater(new Runnable(){
    public void run() {
    wd.setVisible(true);
    }});

    if(args.length>0){
    //if we go in here the progress bar moves slowly and irratically
    SwingUtilities.invokeLater(new Runnable(){
    public void run() {
    doWork();
    }});
    }else{
    //if we go in here the progress bar moves smoothly
    doWork();
    }
    }

    private static void doWork(){
    System.out.println("Calling Thread name is
    "+Thread.currentThread().getName());
    Thread worker = new Thread(){
    public void run() {
    //run long running process in a new thread
    LRP(5000);
    }
    };
    worker.start();
    }

    private static void LRP(int ms) {
    Date startTime = new Date();
    long time = startTime.getTime();
    boolean running = true;
    Date latest = null;
    System.out.println("Delay Thread name is
    "+Thread.currentThread().getName());
    while (running) {
    latest = new Date();
    running = ((latest.getTime() - time) < ms);
    //Adding the following code fixes the problem
    /*
    synchronized(startTime){
    try{
    startTime.wait(100);
    }catch(InterruptedException e){

    }
    }
    */
    }
    }

    }
    , Sep 1, 2005
    #1
    1. Advertising

  2. I believe your problem may be one of inheriting thread priority.
    It is described in more detail here:
    http://java.sun.com/developer/JDCTechTips/2005/tt0727.html#1

    You can try inserting my line below:

    >private static void doWork(){
    >System.out.println("Calling Thread name is
    >"+Thread.currentThread().getName());
    >Thread worker = new Thread(){
    >public void run() {
    >//run long running process in a new thread
    >LRP(5000);
    >}
    >};


    worker.setPriority(Thread.NORM_PRIORITY);

    >worker.start();
    >}


    Cheers
    Bent D
    --
    Bent Dalager - - http://www.pvv.org/~bcd
    powered by emacs
    Bent C Dalager, Sep 1, 2005
    #2
    1. Advertising

  3. Guest

    In article <>,
    <> wrote:
    >I am trying to diagnose some problems with a WaitDialog implementation,
    >i.e. a dialog which is displayed whilst a long running process (LRP)
    >runs.
    >I have pared down the code to a bare minimum for debugging purposes
    >(this code is attached to the end of this post).
    >The WaitDialog simply an indeterminate progress bar (one which moves up
    >and down Night ider style).
    >The main method of this code simply launches the wait dialog and then
    >runs a method, doWork(), which runs the LRP in a **NEW THREAD**.
    >If both the dialog and the method call are launched/invoked in the
    >EventDispatchThread using invokeLater() the progress bar motion is
    >sluggish.
    >This does not make sense to me since the LRP running in doWork() is
    >launched in a new thread.
    >Furthermore if the code in the LRP is changed to periodically
    >relinquish the cpu (using Object.wait(int ms)) the problem goes away.


    I doubt this has much to do with the problem you're reporting, but
    as an "FYI": wait() is not really the way to go if what you want is
    to relinquish the CPU, or to pause for a specified amount of time.
    For the former, Thread.yield() seems more appropriate, and for the
    latter, Thread.sleep(). wait() is meant to work with notify() or
    notifyAll() as a way of waiting for a desired condition to become true.

    >I cannot rationalise this behaviour since my understanding is that if
    >the LRP is running in a separate thread it should have no noticeable
    >affect on work done in other threads.


    How many processors do you have? if more than one, this might be
    true; if only one, all threads must share it, so wouldn't you expect
    to notice changes in performance when you add a thread? Maybe I'm
    misunderstanding.

    "FWIW", maybe. I notice that someone else has posted a suggestion
    about thread priority that might come closer to solving your actual
    problem.

    >I have tried running on JRE 1.4.2, 1.5 on Win2K and WinXP.
    >
    >Any ideas would be greatly appreciated.
    >
    >Code follows:
    >
    >import java.awt.*;
    >import java.util.Date;
    >import javax.swing.*;
    >public class WaitDialog extends JDialog {
    >
    >JProgressBar jProgressBar1 = new JProgressBar();
    >
    >public WaitDialog(Frame owner, String title) {
    >super(owner, title, true);
    >_construct();
    >}
    >private void _construct() {
    >JPanel panel = new JPanel();
    >panel.setLayout(new GridBagLayout());
    >jProgressBar1.setIndeterminate(true);
    >panel.setBorder(BorderFactory.createEtchedBorder());
    >panel.add(jProgressBar1, new GridBagConstraints(0, 1, 2, 1, 0.0, 0.0,
    >GridBagConstraints.SOUTH,GridBagConstraints.BOTH, new Insets(0, 10, 5,
    >10), 140, 0));
    >setContentPane(panel);
    >}
    >
    >public static void main(String args[]) {
    >final JFrame frame = new JFrame();
    >final WaitDialog wd = new WaitDialog(frame, "Waiting...");
    >wd.pack();
    >SwingUtilities.invokeLater(new Runnable(){
    >public void run() {
    >wd.setVisible(true);
    >}});
    >
    >if(args.length>0){
    >//if we go in here the progress bar moves slowly and irratically
    >SwingUtilities.invokeLater(new Runnable(){
    >public void run() {
    >doWork();
    >}});
    >}else{
    >//if we go in here the progress bar moves smoothly
    >doWork();
    >}
    >}
    >
    >private static void doWork(){
    >System.out.println("Calling Thread name is
    >"+Thread.currentThread().getName());
    >Thread worker = new Thread(){
    >public void run() {
    >//run long running process in a new thread
    >LRP(5000);
    >}
    >};
    >worker.start();
    >}
    >
    >private static void LRP(int ms) {
    >Date startTime = new Date();
    >long time = startTime.getTime();
    >boolean running = true;
    >Date latest = null;
    >System.out.println("Delay Thread name is
    >"+Thread.currentThread().getName());
    >while (running) {
    >latest = new Date();
    >running = ((latest.getTime() - time) < ms);
    >//Adding the following code fixes the problem
    >/*
    >synchronized(startTime){
    >try{
    >startTime.wait(100);
    >}catch(InterruptedException e){
    >
    >}
    >}
    >*/
    >}
    >}
    >
    >}
    >



    --
    | B. L. Massingill
    | ObDisclaimer: I don't speak for my employers; they return the favor.
    , Sep 2, 2005
    #3
  4. wrote:
    >
    > I doubt this has much to do with the problem you're reporting, but
    > as an "FYI": wait() is not really the way to go if what you want is
    > to relinquish the CPU, or to pause for a specified amount of time.
    > For the former, Thread.yield() seems more appropriate, and for the
    > latter, Thread.sleep(). wait() is meant to work with notify() or
    > notifyAll() as a way of waiting for a desired condition to become true.


    A reasonable program or thread should quit when told to. If wait is used
    you can set a flag and notify. With Thread.sleep you need to interrupt.
    Thread.interrupt is problematic. You don't want to interrupt a thread
    that is in the middle of writing to a file, say.

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Sep 2, 2005
    #4
  5. Guest

    In article <43183800$0$97137$>,
    Thomas Hawtin <> wrote:
    > wrote:
    >>
    >> I doubt this has much to do with the problem you're reporting, but
    >> as an "FYI": wait() is not really the way to go if what you want is
    >> to relinquish the CPU, or to pause for a specified amount of time.
    >> For the former, Thread.yield() seems more appropriate, and for the
    >> latter, Thread.sleep(). wait() is meant to work with notify() or
    >> notifyAll() as a way of waiting for a desired condition to become true.

    >
    >A reasonable program or thread should quit when told to. If wait is used
    >you can set a flag and notify. With Thread.sleep you need to interrupt.
    >Thread.interrupt is problematic. You don't want to interrupt a thread
    >that is in the middle of writing to a file, say.


    So, are you saying that if all you want to do is pause for some
    specified period time you should use the wait/notify mechanism,
    rather than Thread.sleep()?

    Interesting. I never thought about doing that (perhaps since I don't
    often think in terms of using wait() with a timeout), but now that I
    do .... Yes, I guess that could be an alternative to using sleep()
    and interrupt(). If you're saying it's better, can you explain further
    why?

    --
    | B. L. Massingill
    | ObDisclaimer: I don't speak for my employers; they return the favor.
    , Sep 3, 2005
    #5
    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. Henry
    Replies:
    5
    Views:
    473
    Jim Cheshire [MSFT]
    Jul 26, 2004
  2. alex
    Replies:
    1
    Views:
    616
    Lau Lei Cheong
    Feb 4, 2005
  3. fooooo
    Replies:
    5
    Views:
    883
    Paul Rubin
    May 3, 2005
  4. Jp Calderone
    Replies:
    1
    Views:
    1,336
    Paul Rubin
    May 24, 2005
  5. Jon Pope

    Worker threads on a webservice?

    Jon Pope, Jan 16, 2007, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    199
    Jon Pope
    Jan 16, 2007
Loading...

Share This Page