1

I'm trying to write small multithread program. Where I want to run same process by multuple threads for different time of frame.

I've created one input file where I have different names to same process and milli seconds the process should run for.

T1|1000
T2|2000
T3|3000
T4|4000
T5|5000

Java Program

package Test;

import java.io.*;

public class MultiProcess {


    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new FileReader("/home/maria/Process.txt"));

        String st;
        while ((st = br.readLine()) != null) {

            String[] records = st.split("|");
            Thread tr = new ProcessExecution(records[0], Integer.parseInt(records[1]));
            tr.start();
        }

        br.close();
    }

    static class ProcessExecution extends Thread {

        int threadTime = 0;
        String processName;

        ProcessExecution(String processName, int x) {
            this.threadTime = x;
            this.processName = processName;

        }

        @Override
        public void run() {

            try {
                System.out.println("ProcessName: " + this.processName);
                Thread.sleep(this.threadTime);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

}

In above code, ProcessExecution have different names which are coming from file and want to sleep the current running thread for specific period of time, which is also coming from file.

I'm getting this weird output

ProcessName: T
ProcessName: T
ProcessName: T
ProcessName: T
ProcessName: T

What am dong wrong and how it can be achieved ?

Thanks

Update

All threads are completing at the same time, it seems. It should be staying alive upto the milliseconds coming from file. What's wrong ?

Maria
  • 452
  • 1
  • 6
  • 20

4 Answers4

0

You need to escape the pipe:

st.split("\\|");

To go with my comments, here's a better overall solution:

public class MultiProcess {
    private static final Logger LOGGER = Logger.getAnonymousLogger();
    public static void main(String[] args) throws IOException, InterruptedException {

    String [] values = new String[] {"T1|1000", "T2|2000", "T3|3000", "T4|4000", "T5|5000"}; 
    ExecutorService executor = Executors.newFixedThreadPool(5);
    for (String val : values) {
        String[] records = val.split("\\|");
        executor.execute(new ProcessExecution(records[0], Integer.parseInt(records[1])));
    }
    executor.shutdown();
}

static class ProcessExecution implements Runnable {

    int threadTime = 0;
    String processName;

    ProcessExecution(String processName, int x) {
        this.threadTime = x;
        this.processName = processName;
    }

    @Override
    public void run() {
       try {
           Thread.sleep(this.threadTime);
            LOGGER.info(String.format("ProcessName: %s", processName));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

}

Ryan
  • 1,762
  • 6
  • 11
  • Its working now. But Is my code correct the way am trying to execute ...? Becasue all threads are completing at the same time, it seems. – Maria Mar 04 '20 at 17:50
  • Your code is fine. What you're running into is thread access to the console. Instead of outputting your values directly, save them off to a list and then output the list. Then you'll see the correct order. Take a look at the CountDownLatch to assist in the final output. – Ryan Mar 04 '20 at 18:20
  • but even if I sleep my one thread for 10 seconds, whole code gets finished in one second. I think something is wrong. Any idea..? – Maria Mar 04 '20 at 18:43
  • Threading is a very complicated subject. What you have to understand is that just because you tell a thread to execute doesn't mean it's going to execute right then. The JVM still has to have the resources to start the process. Starting a thread simply tells the JVM to "do this work", it decides when to do the work. Trying using a Logger instead of System.out to do your output, switch your class to implements Runnable instead of extending Thread and take a look at Executors and ExecutorService (Executors.newFixedThreadPool()) should meet your needs just fine. – Ryan Mar 04 '20 at 18:55
0

"|" is a special character and needs to be escaped. Replace String[] records = st.split("|"); with String[] records = st.split("[|]"); and it will work. It is explained here: https://javarevisited.blogspot.com/2017/01/how-to-split-string-based-on-delimiter-in-java.html

Alternatively you can replace it with String[] records = st.split("\\|");

Snusifer
  • 485
  • 3
  • 17
0

When you do

String[] records = st.split("|");

The records array will have

0 = "T"
1 = "1"
2 = "|"
3 = "1"
4 = "0"
5 = "0"
6 = "0"

You should do it as

String[] records = st.split("\\|");

as | is a special character

midhun mathew
  • 333
  • 1
  • 9
0

As others have noted, you need to use st.split("\\|") to get T1 instead of T.

As per the right values being printed in the right order, you want to first sleep for 1000ms, for example, and only then print a message:

        try {
            Thread.sleep(this.threadTime);
            System.out.println("ProcessName: " + this.processName);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
berezovskyi
  • 3,133
  • 2
  • 25
  • 30
  • But don’t you think so, the way am doing code run should stay alive at least for the milliseconds I’ve mentioned...? What’s a point of changing the order like you said ...? – Maria Mar 04 '20 at 18:55
  • Oh yes, I missed that. You need to have both the sleep before printing and also to await termination of all threads in the main(). See https://stackoverflow.com/questions/7939257/wait-until-all-threads-finish-their-work-in-java for info on how to do that. My suggestion to sleep first came from the assumption you want the statements printed after 1000, 2000 etc milliseconds for each thread respectively. If you print first, all print statements will show up in random order nearly immediately and then threads will just sleep unless interrupted. – berezovskyi Mar 04 '20 at 22:17
  • But if it’s a real problem you are trying to solve and not just a homework assignment, I recommend you to learn about thread pools and ExecutorService. – berezovskyi Mar 04 '20 at 22:19