3

Here is my code

while (true) {
    try {
        Thread.sleep(5 * 60 * 1000);
        processData();// data processing job
    } catch (InterruptedException e) {
        SystemMessageBillPay.getInstance().writeMessage("ERROR: CEB.run() - " + e.getMessage());
    } catch (NumberFormatException e) {
        SystemMessageBillPay.getInstance().writeMessage("ERROR: CEB.run() - " + e.getMessage());
    }
}

to this

"Thread.sleep(5 * 60 * 1000);"

code inspector give warning

"Invoking Thread.sleep in loop can cause performance problems"

What should be the code to prevent this warning

Bilesh Ganguly
  • 3,792
  • 3
  • 36
  • 58
virajwee
  • 76
  • 1
  • 7
  • 1
    Instead of having an infinite loop with a sleep to periodically run jobs, use for example a [`ScheduledExecutorService`](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html) to schedule a task to be executed every 5 minutes. – Jesper Jun 21 '16 at 08:02
  • I have changed the duplicated as the original link was talking about busy waiting and not wanting to sleep. – Peter Lawrey Jun 21 '16 at 08:14
  • Your code does have one serious problem: if `sleep()` gets interrupted, your `processData()` won't be called. If that happens often, your work won't get done. And the best answer depends on what exactly you want your code to do. Run every five minutes exactly with no deviations? Run about every 5 minutes and sometimes sooner? – Andrew Henle Jun 21 '16 at 09:17
  • 1
    It is interesting that the alternatives offered so far, do not explain what is the performance problem they are actually solving. As such they are just different ways to achieve a similar thing. – David Soroko Dec 09 '20 at 07:27

4 Answers4

8

With 1.8, you could also use:

import java.util.concurrent.locks.LockSupport;

LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(1000));

As per the Javadoc:

Disables the current thread for thread scheduling purposes, for up to the specified waiting time, unless the permit is available.

The good part is that, its signature does not throw a checked exception. So you don't have to try-catch (unlike Thread.sleep, which requires its InterruptedException to be handled). Of-course, each has its own applicable uses.

Jatin
  • 31,116
  • 15
  • 98
  • 163
2
Is there a alternative to Thread.sleep

Yes, there are ways. But,

It looks like you want to schedule some job. You can either use TimerTask or ScheduledExecutorService instead of this. So later part of your question is about the

"Invoking Thread.sleep in loop can cause performance problems"

and this will solve with scheduling the task.

Scheduling the Task.

public class Test extends TimerTask{

public static void main(String[] args) {
  Test task = new Test();
  Timer timer = new Timer();
  Calendar today = Calendar.getInstance();
  today.set(Calendar.HOUR_OF_DAY, 13);
  today.set(Calendar.MINUTE, 47);
  today.set(Calendar.SECOND, 0);
  timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
}

 @Override
public void run() {
 System.out.println("Running Scheduled Task...!!!");
}
}
Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
0

You need to use a stopwatch timer for this task instead of a thread. Use this: org.apache.commons.lang.time.StopWatch described here: http://commons.apache.org/lang/

AhmadWabbi
  • 2,253
  • 1
  • 20
  • 35
0

Or you van use Quartz. It is an external library:

http://www.quartz-scheduler.org/

Stefan
  • 832
  • 8
  • 10