Making a Thread to Sleep for 30 minutes - java

I want to make my thread to wait for 30 minutes. Are there any problems of doing this?

You can make your thread sleep for 30 minutes like this:
Thread.sleep(30 * // minutes to sleep
60 * // seconds to a minute
1000); // milliseconds to a second
Using Thread.sleep is not inherently bad. Simply explained, it just tells the thread scheduler to preempt the thread. Thread.sleep is bad when it is incorrectly used.
Sleeping without releasing (shared) resources: If your thread is sleeping with an open database connection from a shared connection pool, or a large number of referenced objects in memory, other threads cannot use these resources. These resources are wasted as long as the thread sleeps.
Used to prevent race conditions: Sometimes you may be able to practically solve a race condition by introducing a sleep. But this is not a guaranteed way. Use a mutex. See Is there a Mutex in Java?
As a guaranteed timer: The sleep time of Thread.sleep is not guaranteed. It could return prematurely with an InterruptedException. Or it could oversleep.
From documentation:
public static void sleep(long millis) throws InterruptedException
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
You could also use, as kozla13 has shown in their comment:
TimeUnit.MINUTES.sleep(30);

The answer of Krumia already perfectly shows how to sleep a running Thread. Sometimes, the requirement to sleep or pause a thread originates from the wish to perform an operation at a later date. If that's the case, you should better use a higher level concept like Timer or ScheduledExecutorService:
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.schedule(operation, 30, TimeUnit.MINUTES);
Where operation is the Runnable you want to execute in 30 minutes.
Using a ScheduledExecutorService, you can also execute operations periodically:
// start in 10 minutes to run the operation every 30 minutes
executor.scheduleAtFixedDelay(operation, 10, 30, TimeUnit.MINUTES);

Related

ScheduledExecutorService task that blocks for longer than its run interval

Question about ScheduledExecutorService.shceduleAtFixedRate - I schedule taskA to run every 500 millis, which blocks for 1000 millis. Now subsequent executions aren't gonna wait the extra 500 millis, but rather commence immediately after the previous one.
taskA acquires an intrinsic lock, which is also (attempted) acquired by a different thread. Since intrinsic locks have no fairness guarantees this thread is running a risk of starvation, so here's my question: Is there a good/clean way to avoid this risk? E.g. schedule the task to run every 1500 millis (doesn't sound very waterproof)? Or do we expect the lock acquisition to exhibit a kind of "amortized fairness"?
Yes, you can use scheduleWithFixedDelay:
Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next. If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor.
So the delay you give is the time between end of last end start of next - ie no overlap between runs.

Behavior of ScheduledExecutorService

I've been wondering about specific case around ScheduledExecutorService in java.
Let,
ScheduledExecutorService = new ScheduledThreadPoolExecutor(2);
service.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//Some task taking longer than schedule period to finish executing.
}
},initialDelay,period,TimeUnit.SECONDS);
in this case, say period is 4 seconds. When the schedular starts to execute after initialdelay, task will be blocked inside while(true) inifinite loop.
My question is after each 4 seconds does a task get scheduled disregarding the execution(unfinished) of previous round of task? Because if this is the case this code will crash eventually after running out of memory.
Help is appreciated.
Thank you.
From the javadoc of scheduleAtFixedRate():
If any execution of this task takes longer than its period, then
subsequent executions may start late, but will not concurrently
execute.
Meaning the task will be started once, but since it never finishes there won't be other invocations. You'll just be wasting one thread in the pool.
The same applies to scheduleWithFixedDelay() since the delay is counted from the time when the previous execution finishes (and since it doesn't finish, no next execution can happen).

Interrupt Runnable that takes hours

I have a ThreadPoolExecutor:
ThreadPoolExecutor service = new ThreadPoolExecutor(N_THREADS, N_THREADS, 0L, TimeUnit.MILLISECONDS, blockingQueue, rejectedExecutionHandler);
The service executes threads implementing the Runnable interface. Each thread processes a file on disk. I found that after several hours, two threads (or cores depending on what htop shows in Linux) were running and had been running for 13 hours. What's even worse is that the remaining cores showed no activity as if they were waiting for the two threads to complete.
Questions:
1 - I have read a lot on how this problem may be resolved but nothing conclusive. As far as I can work out, you CANNOT stop a Runnable using the ThreadPoolExecutor because it is an independent thread that just runs. Using the Future framework:
Future<?> f = f.get(submittedtask,XX)
allows you to set a timeout and fetch the future result, but get blocks all the threads effectively making the implementation serial. Is it possible to interrupt a Runnable after a given time using the threadpoolexecutor, get the thread back to the pool so it can pickup a new task and carry on.
2 - My big concern is why, using htop, I see two threads/cores running and no other core/thread are running despite many tasks are still waiting to execute (i.e. there are many files left to process). Any insight?
You could create a second scheduled thread pool to which you would submit cancellation tasks for each of the returned Futures. Each of these tasks after a given timeout would check if it's associated Future is done and if not, cancel it. Cancellation would trigger thread interruption, so you might need to support it in your tasks by checking the interrupted flag: Thread.interrupted().
The size of this second thread pool could be minimal, i.e. 1 as this job takes minimum of CPU time.
Code example:
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
...
while(...){
final Future<?> f = pool.submit(...);
service.schedule(new Runnable() {
#Override
public void run() {
if(!f.isDone()){
f.cancel(true);
}
}
}, 1, TimeUnit.MINUTES);
}
service.awaitTermination(1, TimeUnit.MINUTES);
service.shutdown();
You can tell a thread that you wish to interrupt:
An interrupt is an indication to a thread that it should stop what it is doing and do something else.
You can interrupt your thread with Future.cancel(true). It's in your responsibility to implement the Runnable in a manner that it obeys that wish by checking its Thread.interrupted() state.
In order to see details about process thread run:
ps -eLf | grep <PROCESS_PID>
Since htop shows you the running processes list, where each process has at least one thread.

Thread.sleep behaving weirdly

I have the following code:
public Move chooseMove(Board board) {
// start parallel thread
this.tn = new TreeNode(this.myboard, this, null);
tn.stop = false;
this.curT = (new Thread(tn));
this.curT.start();
try {
long startTime = System.currentTimeMillis();
Thread.sleep(4000 );
System.out.println(System.currentTimeMillis() - startTime);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
tn.stop=true;
return getBestMove();
}
}
The output is sometimes a value that is way greater than 4000ms like 5400ms which means that the thread is sleeping more than it should. Any help?
Thanks.
EDIT:
I understand that there is NO guarantee of Thread#sleep stoping precisely after the specified delay. However, an additional 1400ms is a long delay. Basically,I am implementing a game player agent and I need a way to run a task and then return a value to the server after 5s (or else the server ends the game). The server is using java.util.Timer.schedule(TimerTask task, long delay). There is only one thread running concurent to the main thread which is this.curT in the code above, so there is ins't really heavy multithreading.
From docs.oracle.com:
Two overloaded versions of sleep are provided: one that specifies the sleep time to the millisecond and one that specifies the sleep time to the nanosecond. However, these sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS. Also, the sleep period can be terminated by interrupts, as we'll see in a later section. In any case, you cannot assume that invoking sleep will suspend the thread for precisely the time period specified.
This is common behavior and it is described in Thread#sleep javadoc:
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
Based on this, there's no guarantee of Thread#sleep stoping the work of the thread by the amount of milliseconds stated in the parameter.
Thread#sleep will make your thread sleep for exactly 4 seconds and then wake up.
Once your thread has woken up the OS scheduler places it in the runnable queue.
When it is next picked by the scheduler it will become a running thread i.e. will occupy the CPU.
So there is an additional delay overhead due to the OS scheduler which can vary per OS, system load etc. This is unrelated to Java

Java: SingleThreadScheduledExecutor & java.util.concurrent.RejectedExecutionException

I am having this problem, I have
private ScheduledExecutorService executor =
Executors.newSingleThreadScheduledExecutor();
and task which is created every 50 millliseconds:
executor.scheduleAtFixedRate(myTask, 0, 50, TimeUnit.MILLISECONDS);
myTask sometimes take a while to complete (like 2-3 seconds or so), but newSingleThreadScheduledExecutor guarantees that next scheduled myTask will wait until the current one completes.
However, I get this error from time to time:
execute: java.util.concurrent.RejectedExecutionException
What should I do? Thanks
Consider what the executor is doing. It is running a single task every 50 milliseconds, as per your instructions. Assuming this task takes less than 50 milliseconds to run, then everything is fine. However, every so often it takes 2-3 seconds to run. When this happens, the executor still tries to execute every 50 milliseconds, but because it only has a single thread, it can't, and rejects those executions that are being triggered while your long-running task is still going. This causes the exception you see.
You have two choices to fix this (assuming you want to stick with a single thread):
Use scheduleWithFixedDelay rather than scheduleAtFixedRate. If you read the javadoc carefully, you'll see that scheduleWithFixedDelay will wait 50 milliseconds between the finishing of one task and the start of the next, so it will never "overlap", even if one of them takes a long time. In contrast, scheduleAtFixedRate will try to execute every 50 milliseconds, regardless of how long each one takes.
Change the way that the executor handles failures to execute. The default is to log an exception, but you can tell it to ignore it, for example. Take a look at the subclasses of of java.util.concurrent.RejectedExecutionHandler, for example DiscardPolicy, which just silently drops the task that can't be run. You can use these by directly constructing ScheduledThreadPoolExecutor and passing in the handler to the constructor, rather than using the Executors factory class.
I suspect option (1) is what you want.
This exception will be thrown when either:
You have shutdown the Executor
The Executor's bounds for its work queue or maximum threads have been exceeded.
I assume the latter is happening. When you execute your task and it takes a long time then subsequent scheduled tasks can not be run because there are not enough threads available in the pool.
Either:
Use use a larger pool size or use cachedThreadPool
Change the rejection policy to for example use ThreadPoolExecutor.CallerRunsPolicy
Create a separate Executor for running the long run tasks and run these from your scheduled task. In actual fact you can do this using the same Executor instance providing that you increase the pool size.
See also ThreadPoolExecutor javadoc
With Java 7 both of them will wait till the first execution is ready and then start the next!
check here:
http://download.java.net/jdk7/archive/b123/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html
or here:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

Categories