2

I am a Java beginner searching for a way to do the following:

  1. Read from a csv file (csvreader) one line at a time.
  2. Do some process with the data from the previous step.
  3. If takes longer than 30 seconds, skip the process and continue with the next line.

I'm having problem with step 3. Do I need to set a timer for this? Do I need to play with my try and catch? What do you suggest?

This is a brief of my code:

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

    CsvReader data = new CsvReader("data.csv");
    data.readHeaders();

    int index = 1;
    int index_max = 50;
    int retry = 0;
    int retry_max = 2;

    while (index < index_max)
    {           
        if (retry == 0)
        {   data.readRecord();

            String Column1 = data.get("COLUMN1");
            String Column2 = data.get("COLUMN3");
            String Column3 = data.get("COLUMN4");
            ...
        }
        else
        {
            //Retry with the same data
        }           

        try {
            //Invoke webservice to send the data and write on DB after validation 

                if (positive.answer == 0)
                {
                    System.out.println("Great!!!");
                    index++;
                    retry = 0;
                }
                else
                {
                    System.out.println("Bummer");
                    index++;
                    retry = 0;
                }
            }                       
        catch (Exception e) {
            if (e instanceof webservice_Exception){
               //The Exception is about the webservice, print it
               index++;
               retry = 0;
            } else {
               //The Exception is about another thing, could be a transmission issue, please retry
               retry++;
               if (retry == retry_max)
               {
                retry = 0;
                index++;
               }                   
            }
        }
    }
    data.close();
}
Rodrick
  • 595
  • 10
  • 27
  • 1
    Take a look here: http://stackoverflow.com/questions/2275443/how-to-timeout-a-thread – Daniel Pereira Jan 28 '16 at 02:27
  • Possible duplicate of [How to stop execution after a certain time in Java?](http://stackoverflow.com/questions/4252187/how-to-stop-execution-after-a-certain-time-in-java) – Hovercraft Full Of Eels Jan 28 '16 at 02:27
  • I guess this is CSV rather than CVS, right? – fge Jan 28 '16 at 02:29
  • 1
    Can you post the code of the thread that procesos the data? That thread must check some condition periodically and, if the timeout expire, then stop its execution – Alejandro Goñi Jan 28 '16 at 02:32
  • The simplest possible thing you could do is poll a timer during your processing of the data and terminate processing when time is up. This allows you to stay in a single-threaded design. – scottb Jan 28 '16 at 04:12

2 Answers2

2

There are tools that help you do what you want.

The one that comes to mind is Guava with its TimeLimiter API.

Here's how to use it:

    TimeLimiter timeLimiter = SimpleTimeLimiter.create(Executors.newSingleThreadExecutor());

MyData data = ... ;

// With Java 8
MyResult result = timeLimiter.callWithTimeout(() -> processData(data), 30, TimeUnit.SECONDS, true);

// Without Java 8
MyResult result = timeLimiter.callWithTimeout(new Callable<MyResult>() {
  @Override public MyResult call() {
    return processData(data);
  }
}, 30, TimeUnit.SECONDS, true);

private MyResult processData(MyData data) {
  ...
  return new MyResult();
}
Renaud
  • 16,073
  • 6
  • 81
  • 79
Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137
0

In your case, I think there's no other way than doing a timer. It could be done much more efficient then I did it but I'd do the third point like this (there might be small mistakes in syntax since I have written this very quickly, but you probably get the point):

boolean restart = false;

private long sTime = 0;
private long stTime = 0;
private boolean rng = false;


Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
        start();
        while (true)
            if (getElapsedTimeSecs() > 30) {
                skipEntry();// method that skips to next entry
                stop();
                Thread.currentThread().interrupt();//kills the thread
                return;
            }
    }
});

//starts counting time and sets it to running
public void start() {
    this.sTime = System.currentTimeMillis();
    this.rng = true;
}

//sets counter it to not running
public void stop() {
    this.stTime = System.currentTimeMillis();
    this.rng = false;
}

//returns elaspsed time in seconds
public long getElapsedTimeSecs() {
    long elapsed;
    if (rng) {
        elapsed = ((System.currentTimeMillis() - sTime) / 1000);
    } else {
        elapsed = ((stTime - sTime) / 1000);
    }
    return elapsed;
}

You should start the thread every time you process a new line.

In this case, you'll need 2 threads instead of one... the process of checking time could be done within your thread! In that case, it would be much easier to implement it and it would be much more efficient! But with no code given, I can't do it better.

Hope this helps.

Regards, Matej

Mysterious Wolf
  • 373
  • 1
  • 5
  • 22
  • thanks for your answer. I published a brief of my code just now. So, I have to use multi threading... I will have to study about that, I am pretty new in Java. I did not understand if the example that you posted is already using 2 threads or this is one thread and my code is another thread? – Rodrick Feb 01 '16 at 15:15
  • When you create and start a new Thread it runs simultaneously with the code that is after the start method. – Mysterious Wolf Jun 25 '16 at 15:06