Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Threads and Swings- UI Hangs..

 
Amer Seifeddine
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Folks,

I have a user interface which allows the user to start a thread.. the Thread starts perfectly but it freezes the ui. Here is the piece of related code (java 1.4.2):

From Action Performed.. starting the thread (LogArea is a TextArea on the ui printing details):

{
progressBar.setVisible(true);

//Create a timer.
timer = new Timer(ONE_SECOND, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
progressBar.setValue(taskThread.getCurrent());
String sMessage = taskThread.getMessage();
if (sMessage != null) {
LogArea.append(sMessage + newline);
}
}
});

//Start the Thread here...
progressBar.setMinimum(0);
progressBar.setMaximum(taskThread.getLengthOfTask());
progressBar.setValue(0);
progressBar.setStringPainted(true);

timer.start();
if(taskThread==null)
taskThread=new TaskThread();
taskThread.startme();
}

Thread (Thying to stop the process from a button which calls the stopprocess method from the action performed but the ui hangs):

public class TaskThread extends Thread
{
private int lengthOfTask;
private int current = 0;
private String sMessage;
private boolean bStateAvailable=true;
private boolean bMessage=false;
private boolean bCurrent=false;
TaskCancellable cancellable;
State2 StateLock;
Integer iCurrentLock;
Integer iMessageLock;
public static final String IDLE="IDLE";
public static final String START="START";
public static final String STOP="STOP";

/** Creates a new instance of mainThread */
public TaskThread()
{
super();
cancellable=new TaskCancellable();
lengthOfTask = 100;
StateLock=new State2();
iMessageLock=new Integer(0);
iCurrentLock=new Integer(0);
bStateAvailable=false;
bMessage=false;
bCurrent=false;
}

public int getLengthOfTask()
{
return lengthOfTask;
}

public int getCurrent()
{
synchronized(iCurrentLock)
{
while(bCurrent==false)
{
try
{
iCurrentLock.wait();
}
catch (InterruptedException e) { };
}
bCurrent=false;
iCurrentLock.notifyAll();
return current;
}
}

public void setCurrent(int x_current)
{
synchronized (iCurrentLock)
{
while(bCurrent==true)
{
try
{
iCurrentLock.wait();
}
catch (InterruptedException e) { };
}
bCurrent=true;
current=x_current;
}
}

public String getMessage()
{
synchronized(iMessageLock)
{
while(bMessage==false)
{
try
{
iMessageLock.wait();
}
catch (InterruptedException e) { };
}
bMessage=false;
iMessageLock.notifyAll();
return sMessage;
}
}

public void setMessage(String x_Message)
{
synchronized (iMessageLock)
{
while(bMessage==true)
{
try
{
iMessageLock.wait();
}
catch (InterruptedException e) { };
}
bMessage=true;
sMessage=x_Message;
}
}

public void setState2(String x_sState)
{
Log.debug("TaskThread.setState2 Started");
synchronized(StateLock)
{
Log.debug("TaskThread.setState2 synchronized block");
StateLock.sState=x_sState;
}
}

public String getState2()
{
Log.debug("TaskThread.getState2 started");
synchronized(StateLock)
{
Log.debug("TaskThread.getState2 Synchronized block");
Log.debug("TaskThread.getState2 notifying");
StateLock.notifyAll();
return StateLock.sState;
}
}

public void startme()
{
Log.debug("TaskThread.startme");
setState2(START);
Log.debug("TaskThread.startme completed");
}

public void kill()
{
/* Log.print("Killing Thread Objects");

if(cancellable!=null)
{
cancellable.cancel();
}
}
*/
}

public void run() {
while(true)
{
try
{
if(IDLE.equals(getState2()))
{
Log.debug("Idle Mode");
sleep(1000);
}
else if(STOP.equals(getState2()))
{
releaseUI();
setState2(IDLE);
Log.debug("Stop Mode");
}
else if(START.equals(getState2()))
{
startProcess();
Log.debug("Busy Mode");
}
else
{
Log.debug("Unkwown Mode");
}
}
catch (InterruptedException e) {Log.debug(e);}
}
}

public void startProcess()
{
Log.debug("TaskThread.startprocess started");
//Start here
for(int i=1;i<1000000000;i++)
{
if(i%10==1)
{

try{
sleep(100);}
catch (InterruptedException e) {Log.debug(e);}
Log.print(""+i);
if(STOP.equals(getState2()))
{
Log.debug("Breaking the loop.. Thread found in Idle mode");
break;
}
}
}
setState2(IDLE);
}

public void stopProcess()
{
Log.debug("TaskThread.stopProcess started.");
setState2(STOP);
Log.debug("TaskThread.stopProcess ended.");
}


}


Any hint please?
 
Henry Wong
author
Marshal
Pie
Posts: 21506
84
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Any hint please?


One possibility... Your timer thread calls the TaskThread.getMessage() method. This method call wait() if a message isn't available.

Since the timer is a swing timer, this means that the wait() is being executed by the event dispatching thread, which means that no other events can be handled, until the wait() method returns. And if the notification is to be done by some other swing event, it will never be called.

Henry
 
Amer Seifeddine
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well. Even by commenting out this part it still hangs... However, you're right and I should handle the getMessage issue.

With the comment of timer, I found out that this is the source of my problem:

public void startProcess()
{
Log.debug("TaskThread.startprocess started");
//Start here
for(int i=1;i<1000000000;i++)
{
if(i%10==1)
{

try{
sleep(100);}
catch (InterruptedException e) {Log.debug(e);}
Log.print(""+i);
if(STOP.equals(getState2()))
{
Log.debug("Breaking the loop.. Thread found in Idle mode");
break;
}
}
}
setState2(IDLE);
}


I should say, return instead of break since I am changing the state to Idle without giving the Thread control to recognize that I am still in stop mode...

I will work out on the timer now and thanks man for your help on wait issue.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic