Worker threads seem to affect gui processing

  • Thread starter anthony.jayasekera
  • Start date

A

anthony.jayasekera

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){

}
}
*/
}
}

}
 
Ad

Advertisements

B

Bent C Dalager

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
 
B

blmblm

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){

}
}
*/
}
}

}
 
T

Thomas Hawtin

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
 
Ad

Advertisements

B

blmblm

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?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top