0

I wanted to know how can you make a thread sleep until a set date like for example a set date 14/Feb/2020.

Thread will remain sleep until this date. is there any way to do that in java?.

Nicktar
  • 5,548
  • 1
  • 28
  • 43
coder
  • 45
  • 9
  • Does this help https://stackoverflow.com/questions/24879303/making-a-thread-to-sleep-for-30-minutes – Shubham Feb 13 '20 at 11:05
  • 1
    The answer on the linked question suggesting to use a ScheduledExecutorService sounds a lot better. – Nathan Hughes Feb 13 '20 at 11:27
  • Would a **cron** like scheduler (running as timer in the background), not be a better solution? Or Nathan's proposal. – Joop Eggen Feb 13 '20 at 11:31
  • Does this answer your question? [Making a Thread to Sleep for 30 minutes](https://stackoverflow.com/questions/24879303/making-a-thread-to-sleep-for-30-minutes) – Nicktar Feb 13 '20 at 11:36

2 Answers2

1

Executor service

Define a Runnable (or Callable). That means simply having a run method to comply with the contract of the interface.

In lambda syntax:

Runnable runnable =
    () -> { 
        System.out.println( "Looking up fresh stock prices at " + Instant.now().toString() ) ; 
    } 
;

Next, study up on the Executors framework built into modern Java. See Oracle Tutorial. This framework greatly simplifies the tricky work of scheduling work on threads.

Specifically, you want to use ScheduledExecutorService. This interface is for scheduling a task to run once at a specific time (actually, run once after a specific delay expires), or run a task repeatedly. You, of course, want the former.

Get an implementation from the Executors class. For your needs, we need only a single-thread. In other cases, you may want to use a thread pool.

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor() ;

Specify how long to wait, a delay, until the task is executed. Calculate the elapsed time needed to wait.

Specify your target date. In real work I would verify that date is indeed in the future.

LocalDate localDate = LocalDate.of( 2020 , Month.FEBRUARY , 23 ) ;

We need a specific moment rather than just a date. I suppose you would want the first moment of that day. Do not assume this is 00:00. Some days in some zones on some dates may start at another time, such as 01:00. Always let java.time determine first moment.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = localDate.atStartOfDay( z ) ;

Convert from that time zone to UTC.

Instant then = zdt.toInstant() ;

Capture the current moment as seen in UTC.

Instant now = Instant.now() ;

Calculate elapsed time as a Duration.

Duration d = Duration.between( now , then ) ;

Now schedule our task to be run after the delay expires. I suggest adding a bit of time to make sure all the clocks of any related systems are well into the new day. Plus midnight tends to be the Witching Hour for computing, with many cron jobs, log-rolling, utilities, and reports running then. Maybe add a few minutes or more.

ses.scheduleWithFixedDelay( runnable , d.plusMinutes( 7 ).toMinutes() , TimeUnit.MINUTES);

You may choose to capture the returned ScheduledFuture to monitor your task.

IMPORTANT Be sure to gracefully shutdown your executor service when no longer needed, or when your app is being shut down. Otherwise your threads may continue running in the background, surviving your app's exit.

ses.shutdown() ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

You could get the current date with System.currentTimeMillis, get milliseconds for the given date (14th of February in your case), calculate the number of milliseconds that separates the current date from a given date, and call sleep() method with this value. I'm not sure what is the practical usage of this, to be honest.

Here's a quick solution:

 public static void main(String[] args) {
    long currentMillis = System.currentTimeMillis();
    long givenDateMillis = LocalDateTime.of(2020, 2, 14, 0, 0, 0)
            .atZone(ZoneId.systemDefault())
            .toInstant()
            .toEpochMilli();

    Thread.sleep(givenDateMillis - currentMillis);
}

I wouldn't recommend using it in any production code, for this sort of case I'd recommend using some sort of a scheduler.

mklepa
  • 211
  • 3
  • 7