One thread is blocking the other
1 posts in topic
Flat View  Flat View
TOPIC ACTIONS:
 

Posted By:   Christian_Schuster
Posted On:   Wednesday, June 25, 2003 10:08 PM

I am not an expert with Threads at all. So it may be that I have a lack of basic knowledge fopr Threads. Well, what I would like to do is to trigger a dailog to show after certain amount of time. Lets say I have a method M. In there I create two thread instances called Worker and Trigger. The Worker thread is just a time consuming thread. The trigger thread is just waiting a certain amount of time and the calls the method show of the dialog. So in method M I start first the worker thread, then the trigger thread and in a while block I am waiting for the worker thread to be finished. After the trigger thread has finished it calls show. But the dialog is never visible. Then worker thread ends but it does not get out of    More>>

I am not an expert with Threads at all. So it may be that I have a lack of basic knowledge fopr Threads.

Well, what I would like to do is to trigger a dailog to show after certain amount of time.

Lets say I have a method M. In there I create two thread instances called Worker and Trigger. The Worker thread is just a time consuming thread. The trigger thread is just waiting a certain amount of time and the calls the method show of the dialog.

So in method M I start first the worker thread, then the trigger thread and in a while block I am waiting for the worker thread to be finished. After the trigger thread has finished it calls show. But the dialog is never visible. Then worker thread ends but it does not get out of the while block, therefore, running for ever.

But if I instead start the trigger thread call the show mehtod of the dialog. All is working fine. The dialog appears and when the worker thread has finished it closes the dialog. But this way I do not have the popup time.

Can anyone point me in the right direction. This would be great.

Here is the code example which I used to test.


import java.awt.*;
import java.awt.event.*;


import javax.swing.*;


class PopupThread extends JFrame implements ActionListener{
private final static int DELAY = 1000; // milli seconds

private final static int WORK = 5000; // milli seconds



private boolean showProgress = true;



private MyDialog dlg = null;

private Worker worker = null;

private Trigger trigger = null;


private JButton b_start = new JButton("Start");



public PopupThread() {

super("Trigger test");



addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

dispose();

System.exit(0);

}

});



getContentPane().add(b_start);



b_start.addActionListener(this);

b_start.setPreferredSize(new Dimension(100, 30));

b_start.setMaximumSize(new Dimension(100, 30));

}



public static void main(String args[]) {

System.out.println("Starting PopupThread...");

PopupThread mainFrame = new PopupThread();

mainFrame.setSize(400, 400);

mainFrame.setTitle("PopupThread");

mainFrame.setVisible(true);

}



/*

* method gets called when start is clicked

*/

private void b_start_clk(){

dlg = new MyDialog(this);

worker = new Worker();

trigger = new Trigger();



dlg.setLocation(50, 50);

dlg.setLocationRelativeTo(this);



worker.start();

if (showProgress){

//trigger.start(); /* this does not work */

dlg.show(); /* this works but this way I do not have the popup time */

}



/* this while block si here because if showProgress is false we

* need to wait for the worker to have finshed

*/

while ( (worker.isAlive()) && (!worker.isInterrupted()) ){

try{

System.out.println("Wait for worker to finish");

Thread.currentThread().sleep(500);

}

catch(InterruptedException e){

System.out.println(e.getMessage());

}

}



System.out.println("Close dialog in frame");

dlg.dispose();

}



public void actionPerformed(ActionEvent ae){

if (ae.getSource() == b_start) b_start_clk();

}




/*

* Just a simple dialog which shows a progress bar

*/

class MyDialog extends JDialog{

private final Dimension DLG_SIZE = new Dimension(200, 30);

private JProgressBar pb = new JProgressBar();



public MyDialog(Frame owner){

super(owner, "Please wait. Performing task", true);

createDialog();

setDialogSettings();

}



private void createDialog(){

getContentPane().add(pb);

}



private void setDialogSettings(){

setSize(DLG_SIZE);

setUndecorated(true);



pb.setIndeterminate(true);

pb.setString("Please wait...");

pb.setStringPainted(true);



}



}



/*

* trigger thread which is just waiting a certain amount of time

*/

class Trigger extends Thread{

public Trigger(){

super();

}



public void run(){

try{

System.out.println("Wainting the popup time");

Thread.currentThread().sleep(DELAY);

System.out.println("Finished waiting the popup time trigger show");

dlg.show();

}

catch(InterruptedException e){

System.out.println(e.getMessage());

}

}

}



/*

* thread to simulate a time consuming task

*/

class Worker extends Thread{

public Worker(){

super();

}



public void run(){

try{

System.out.println("Start working...");

Thread.currentThread().sleep(WORK);

System.out.println("Finished working");

}

catch(InterruptedException e){

System.out.println(e.getMessage());

}



/* close dialog again */

try{

System.out.println("Close dialog in worker");

dlg.dispose();

}

catch(Exception e){

System.out.println(e.getMessage());

}

}

}

}

   <<Less

Re: One thread is blocking the other

Posted By:   Iuga_Marin  
Posted On:   Saturday, June 28, 2003 02:24 AM

Well,
you should use two monitor objects, one for the worker thread and one for the trigger thread.

So, the flow should be as follows:



- you should create two objects, let's call them workerMonitor and triggerMonitor (at least java.lang.Object instances).


- in the b_start_clk create the Worker thread and pass the WorkerMonitor object.

Start the worker thread and call:

  synchronized(workerMonitor) {workerMonitor.wait();}

in order to wait for the thread execution.


- in the run method of the Worker thread, just before exiting the method, perform the following call:

  synchronized(workerMonitor_) {workerMonitor_.notify();}

where the workerMonitor_ is the instance attribute storing the passed workerMonitor object.


- do the same thing with the Trigger thread and TriggerMonitor object.



Basically, b_start_clk will have to start the Worker thread and wait on the WorkerMonitor using wait method until the Worker thread will free the monitor using notify method.

Same for the Trigger thread.



As a general rule, do no use while blocks to ensure thread synchronization because is resource consumming and potentially error-prone.
Use Object.wait() and Object.notify() in syncronized blocks
.




  I hope this helps, Marin.

About | Sitemap | Contact