Link to home
Start Free TrialLog in
Avatar of Tolgar
Tolgar

asked on

How to write multi-threaded code in Java?

Hi,
I am writing a Java code and in this code, I call an external command by using cmd.exe and I run a batch file. Everything works fine up to this point. However, this is a UI application and after it calls the external command, the UI just waits for the other process to be completed and it you cannot click on any other button in the UI because it is just unresponsive.

As I talk to my colleagues, they recommended me to do multi-threading to solve this problem. Basically, I need to create another thread and then I need to run the external command in this thread. As a result I will be able to use the UI during the time the newly created thread is busy. This way I will use the UI and by using the stop button I will be able to stop this process at any time want.

However, I have never done anything about multi-threading until now and I am in a time pressure. I need to know how to create a new thread and do some processes in this thread.

Can you please help me how I should do this?
ASKER CERTIFIED SOLUTION
Avatar of MajorBigDeal
MajorBigDeal
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Tolgar
Tolgar

ASKER

I use Runtime.getRuntime().exec and this is the code that I run this external command and even though I don't use waitFor() the code just halts until the process is finished.

Can you please take a look at the code that I have? Could there be a problem/bug at line 22 where I have the while loop?

                    tempDir = "C:/Temp/mgcheck";
                    setMgcheckPathCmd = "cmd.exe /C mg.bat -using A 
                    batchFileCmd = "cmd.exe /C \\\\somePath\\mgcheckGui.bat" +" " + Location + " " + fileInfoLine + " " + checkList ;
                
                perlCmd = batchFileCmd;
                Runtime mgcheck_runtime = Runtime.getRuntime();
                
    
                try {
                    mgcheck_process = mgcheck_runtime.exec(perlCmd, environment);
                } catch (Exception e) {
                    System.out.println("error executing " + perlCmd);
                }
                
    
                /* dump output stream */
                InputStream is = mgcheck_process.getInputStream();
                BufferedReader reader = new BufferedReader
                    ( new InputStreamReader(is));
                String commandLineOutput;
                String resultsXML = null;
                while ((commandLineOutput = reader.readLine()) != null) {
                    Pattern p = Pattern.compile("\\d{8}_\\d{4}_\\d{2}_Mgcheck.xml");
                    Matcher m = p.matcher(commandLineOutput);
                    if (m.find()){
                        resultsXML = m.group();                       
                    }
                    System.out.println(commandLineOutput);
                }
                System.out.flush(); 

Open in new window

SOLUTION
Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Simplified dem, but this shows how a task can run and leave the GUI buttons operational. Hope it helps. Obviously.

import javax.swing.*;
import java.awt.*;
import java.net.*;
import java.util.*;
import java.awt.event.*;

class Asynch extends JFrame implements ActionListener{

static JButton j,jst;
static Asynch a;
static volatile boolean taskunderway = false;
static int times = 1;

  public static void main(String[] args){

	a = new Asynch();

	j = new JButton("Click to start task");

	jst = new JButton("Click to stop task");

	a.setLayout(new BorderLayout());

	a.getContentPane().add(j,BorderLayout.CENTER);
	a.getContentPane().add(jst,BorderLayout.SOUTH);

	a.setSize(new Dimension(350,100));

	a.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

	a.setVisible(true);

	j.addActionListener(a);
	jst.addActionListener(a);
	
  }

 static class Task implements Runnable{

	public void run(){

		try{
	     	Thread.sleep(2000);
		}catch(Exception e2){}
		j.setBackground(java.awt.Color.GREEN);

		taskunderway=true;
		j.setText(" . . . running . . . ");
		while((taskunderway&&a.isVisible())){System.out.println(new Date());}	
		System.out.println("Task ended.");	
		times = 1;	
	}

  }


  public void actionPerformed(ActionEvent e){

		
		if(((JButton)e.getSource()).getText().equals("Click to stop task")&&taskunderway){
			
			taskunderway = false;
			System.out.println("Stopping task");
			j.setText("Click to start task");
			j.setBackground(jst.getBackground());
			return;

		}
		if(((JButton)e.getSource()).getText().equals("Click to stop task")&&!taskunderway){return;}
		
		if(!taskunderway){
		  j.setBackground(java.awt.Color.RED);
		  Thread th = null;	
		  th = (new Thread(new Task()));
		  th.start();
		}
		else{j.setText("Said I'm running "+(times++)+" times now!");/*try{
	     	Thread.sleep(2000);
		}catch(Exception e2){}j.setText(" . . . running . . . ");*/}
						
  }

}

Open in new window

Avatar of Tolgar

ASKER

@krakatoa: can you please show me how I can implement it in the code that I posted above.

Thanks,
The idea of my example was how a task from the main thread can be delegated to a separate process, that's all. I thought you were looking for how to approach multi-threaded code.

I am not going to implement it in your code, sorry.

Otoh, there's more reason to adopt CEHJ's proposal, since what I've tried to illustrate is almost certainly not as OOP-PC as Swingworker, and his expert opinion is always to be favoured in this TA.