I want to execute a Java program in Eclipse multiple times with a certain delay.
I was trying to use ScheduleAtFixedRate() to re-execute the program after a certain interval of time. So what is the main difference between ScheduleAtFixedRate() and ScheduledExecutorService?
What is the advantage of using the latter?
Does it continue running the schedule of execution when the computer is set on a sleep mode?
Provided you mean .scheduleAtFixedRate() (note the little s), then it is a method provided by ScheduledExecutorService. As such, there is no {dis,}advantage to using either.
You can create a ScheduledExecutorService by calling, for instance:
final ScheduledExecutorService service
= Executors.newScheduledThreadPool(...);
service.scheduleAtFixedRate(...);
As to:
Does it continue running the schedule of execution when the computer is set on a sleep mode?
No. It is the OS which puts the computer to sleep, and it is the OS which you should instruct to wake up at the time(s) you want. A running Java program is a JVM is a process is ultimately controlled by the OS.
ScheduledExecutorService is an interface that defines the behaviour of a task executor and ScheduleAtFixedRate() is method of this interface which expects the implementation class i.e the executor to execute the input task at fixed interval.
When your computer goes to sleep or hibernates nothing will execute.
Related
In my Java application I have a Runnable such as:
this.runner = new Runnable({
#Override
public void run() {
// do something that takes roughly 5 seconds.
}
});
I need to run this roughly every 30 seconds (although this can vary) in a separate thread. The nature of the code is such that I can run it and forget about it (whether it succeeds or fails). I do this as follows as a single line of code in my application:
(new Thread(this.runner)).start()
Now, this works fine. However, I'm wondering if there is any sort of cleanup I should be doing on each of the thread instances after they finish running? I am doing CPU profiling of this application in VisualVM and I can see that, over the course of 1 hour runtime, a lot of threads are being created. Is this concern valid or is everything OK?
N.B. The reason I start a new Thread instead of simply defining this.runner as a Thread, is that I sometimes need to run this.runner twice simultaneously (before the first run call has finished), and I can't do that if I defined this.runner as a Thread since a single Thread object can only be run again once the initial execution has finished.
Java objects that need to be "cleaned up" or "closed" after use conventionally implement the AutoCloseable interface. This makes it easy to do the clean up using try-with-resources. The Thread class does not implement AutoCloseable, and has no "close" or "dispose" method. So, you do not need to do any explicit clean up.
However
(new Thread(this.runner)).start()
is not guaranteed to immediately start computation of the Runnable. You might not care whether it succeeds or fails, but I guess you do care whether it runs at all. And you might want to limit the number of these tasks running concurrently. You might want only one to run at once, for example. So you might want to join() the thread (or, perhaps, join with a timeout). Joining the thread will ensure that the thread will completes its computation. Joining the thread with a timeout increases the chance that the thread starts its computation (because the current thread will be suspended, freeing a CPU that might run the other thread).
However, creating multiple threads to perform regular or frequent tasks is not recommended. You should instead submit tasks to a thread pool. That will enable you to control the maximum amount of concurrency, and can provide you with other benefits (such as prioritising different tasks), and amortises the expense of creating threads.
You can configure a thread pool to use a fixed length (bounded) task queue and to cause submitting threads to execute submitted tasks itself themselves when the queue is full. By doing that you can guarantee that tasks submitted to the thread pool are (eventually) executed. The documentation of ThreadPool.execute(Runnable) says it
Executes the given task sometime in the future
which suggests that the implementation guarantees that it will eventually run all submitted tasks even if you do not do those specific tasks to ensure submitted tasks are executed.
I recommend you to look at the Concurrency API. There are numerous pre-defined methods for general use. By using ExecutorService you can call the shutdown method after submitting tasks to the executor which stops accepting new tasks, waits for previously submitted tasks to execute, and then terminates the executor.
For a short introduction:
https://www.baeldung.com/java-executor-service-tutorial
I'm using a ScheduledExecutorService to run a particular job (implemented as an ordinary Runnable) periodically once in a minute (using method scheduleAtFixedDelay()).
Occasionally, however, I would like it to wake up immediately, invoke the Runnable and then return to its ordinary policy (i.e. wait 1 minute again).
Is there a simple way to achieve this?
I've checked the API of the ScheduledExecutorService and its superclasses, but so far didn't find anything suitable.
Of course I could resort to some other method, like pass the same Runnable to a separate Thread created for the exceptional purpose, but using a method of the ScheduledExecutorService would be more elegant.
Just remember the ScheduledFuture from your call to schedule.
If you then want to run it ahead of time, call future.cancel(), submit the Task again for immediate execution and then schedule it again.
I have been going through some of the SO questions about doing something after a specific interval of time (like printing hello world every five seconds).
I saw different ways that we can do it in a java program. my question is how java does this internally.
Once we run a java program, the main function starts executing in a thread. But this thread can be sent to Runnable state anytime(pause the execution). So if I had stated the print statement in the main function, how does java keep track of time now. what if the java program was not resumed for the next five seconds?
One way this could work is if we meant "every 5 seconds in the time period which the java program is running" . Is that how the JVM does this?
Assume that I have a single processor.
Ok, lets trace the calls. If we are using ScheduledThreadPoolExecutor we can find that it uses DelayedWorkQueue internally:
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue());
To await next tasks DelayedWorkQueue uses Condition available = lock.newCondition():
available.awaitNanos(delay);
Ok, lets take a look at awaitNanos implementation in AbstractQueuedSynchronizer:
LockSupport.parkNanos(this, nanosTimeout);
And the LockSUpport:
unsafe.park(false, nanos);
This is native method which uses operating systems's scheduler to delay thread execution.
I am working on a Java program and using Timer objects to run tasks every few minutes or hours. This works fine in normal operations, but I am running into a problem with "Sleep mode" on Mac (maybe on other OSes, but I haven't tried yet).
Consider this code sample:
//Setup the timer to fire the ping worker (every 3 minutes)
_PingTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Program.PingThread = new PingWorker(Settings.Username, Settings.UserHash, true, true);
Program.PingThread.CheckOpenPort = true;
Program.SwingExecutor.execute(Program.PingThread);
}
}, 0, 180000);
In normal operation this would fire every 3 minutes with enough accuracy (I'm not concerned about the exact second or anything). The problem with this is after sleeping the computer for a few hours or so it seems to just BLAST the system with backlogged timer requests.
It seems to be running all of the missed timer hits during sleep at once trying to make up for lost time.
Is there a way i can prevent this? I tried using synchronized and some other thread techniques, but this only ensures that they aren't all running at the same time. They still continue to run one after another until the backlog is passed.
Thanks for any help you can provide!
Have you looked at the API? It clearly states the following:
In fixed-rate execution, each
execution is scheduled relative to the
scheduled execution time of the
initial execution. If an execution is
delayed for any reason (such as
garbage collection or other background
activity), two or more executions will
occur in rapid succession to "catch
up." In the long run, the frequency of
execution will be exactly the
reciprocal of the specified period
(assuming the system clock underlying
Object.wait(long) is accurate).
This is one reason why you should consider using a ScheduledExecutorService. This link may also prove useful.
Use schedule instead of scheduleAtFixedRate.
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