Eclipse : ScheduledExecutorService.scheduleWithFixedDelay does not remove on publish - java

I got weird problem.
I have a ScheduledExecutorService.scheduleWithFixedDelay which doesn't not "stop" when i click publish / stop-restart server .
When i republish, there will be 2 service running and the number of same service running depends on how many times I click publish.
This does not go away after I stop and start server.
I have to close eclipse and open to stop it and I notice this happen only after i edit the class that initialize the service.
I'm unable to paste the codes but is very simple.. just a Singleton and holds the service
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() { system.out("hello" }
}, 60 * 60, SECONDS);
I can't seems to find out the issue, can someone help me please.

You're supposed to shut down the scheduler when the application is undeployed. The easier way to do that is to declare an implement a ServletContextListener, and shut down the schedler in the contextDestroyed() method.

Executors.newScheduledThreadPool(1); creates a non-daemon worker thread and it prevents JVM from shutting down unless you shutdown scheduler explicitly
scheduler.shutdown();
alternatevely, you can do the following
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1,
new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(false);
return t;
}
});
in this case the worker thread will be a daemon and will not prevent the JVM from exiting when the program finishes

Related

Spring Java #Scheduling configuration

Using #Scheduling to run method at #Scheduled(fixedRate = 10000) and set up #Scheduling threading by implementing SchedulingConfigurer
#Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(10);
}
if I used Thread.sleep or Lock , no other thread is created by Executor unless Thread.sleep wake up or lock is cleared.
Can someone explain internal working if i have 10 pool size they 10 threads should be created at rate of 10000 millisec.
Basically such behavior comes from ScheduledExecutorService implementation which is used internally by spring. If you will run this code you will notice the same behavior:
public static void main(String[] args) throws Exception {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
executor.schedule(() -> {
System.out.println("Running task in thread " + Thread.currentThread().getId());
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
System.out.println("interrupted while sleeping");
}
}, 1000, TimeUnit.MILLISECONDS);
Thread.sleep(10000);
executor.shutdownNow();
}
When you submit task to scheduled thread pool it is wrapped with RunnableScheduledFuture which is passed to delayedExecute method. This method adds the task to the tasks queue and starts new worker if current number of workers is less than corePoolSize. Worker tries to get a task from the queue and process it invoking run method. There is a dedicated DelayedWorkQueue implementation which returns tasks only if they are ready for execution. Here is how run method of RunnableScheduledFuture looks like:
/**
* Overrides FutureTask version so as to reset/requeue if periodic.
*/
public void run() {
boolean periodic = isPeriodic();
if (!canRunInCurrentRunState(periodic))
cancel(false);
else if (!periodic)
ScheduledFutureTask.super.run();
else if (ScheduledFutureTask.super.runAndReset()) {
setNextRunTime();
reExecutePeriodic(outerTask);
}
}
As you can see it invokes actual task logic in runAndReset, calculates the next running time and submits the same updated task to the queue again (reExecutePeriodic is almost the same as schedule). There is only a single periodic task for all executions which is resubmitted again and again with updated time after the previous execution is finished. So such thread pool runs only a single instance of each task type in any given moment and scales only for different type of tasks.
If you are interesting in how spring schedules tasks take a look at ScheduledTaskRegistrar class and particularly at scheduleFixedDelayTask method.
In the case that you use threadpool:
By default you going to have 10 threads in your pool(already initialized). The first time that #scheduled is executed, this function is going to execute in a thread from your pool (now remaining 9 threads), if the function yet finished and #scheduled is executed again, your function going to executed in other thread from you your pool, so now you have 8 thread remaining in your pool. (8 idle, 2 running threads)
If you aren`t use threadpool only one thread is used.
spring documentation:
If you do not provide a 'pool-size' attribute, the default thread pool
will only have a single thread. There are no other configuration
options for the scheduler.
https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/scheduling.html

java ScheduledExecutorService task stops after several executions

I have a problem, I am trying to execute a Task in ScheduledExecutorService, and I am executing the task with the command:
updateTagDataHandle = scheduler.scheduleWithFixedDelay(updateTagDataRunnable, 500, 500, TimeUnit.MILLISECONDS);
and after several success runs it stops. the task itself takes a few seconds I checked with println that it go to the end of the task with no errors, and I print any exception and didnt see an exception in the end. I need it to continue run infinite number of times.
any help would be appreciated
edit
my code for initializing the task scheduler was:
scheduler = Executors.newScheduledThreadPool(1);
so the corePoolSize = 1 so there only one thread alive and the task share this on thread. but setting the threadPool to be more than one is not helping and still there seems to be only one thread active.
same question here:
Executors Factory method newScheduledThreadPool always returns the same Thread pool
and here:
Why doesn't ScheduledExecutorService spawn threads as needed?
any help would be appreciated
edit:
didnt find a solution so used the scheduler custom thread creation :
scheduler = Executors.newScheduledThreadPool(7, new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
});
Try changing the initial delay to 1000 milliseconds.
I was trying the same code in my android app and this solved the problem.

Executors.newFixedThreadPool hanged threads

As it said in javadoc
The threads in the pool will exist
until it is explicitly shutdowned by ExecutorService#shutdown()
If I have a web application on Tomcat. On startup It creates a fixed thread pool. Also I have investigated
public static void main(String ... strings) {
ExecutorService s = Executors.newFixedThreadPool(2);
s.submit(new Runnable() {
public void run() {
System.out.println("zzz");
}
});
}
that threads in the above example don't exist until I submit them to ExecutorService. When main method ends I see a javaw.exe in the list of processes of the task manger(win 7 os). So I assume that instance of the jvm that run that example still exists. When I add s.shutdown() - there are no any java process in the process list.
Question 1: when the tomcat suddenly stops due to some errors, will the java process hang in the memory(if previously some tasks were submitted to thread pool mentioned above);
Question 2: if the answer to previouse question is yes, are there some ways to make threads in pool to be deamon or maybe are there some ways to handle such tomcat/myapp stops to invoke ExecutorService#shutdown()
Question 1: when the tomcat suddenly stops due to some errors, will the java process hang in the memory(if previously some tasks were submitted to thread pool mentioned above);
If it doesn't shutdown the ExecutorService then yes, it will hang.
Question 2: if the answer to previouse question is yes, are there some ways to make threads in pool to be deamon...
Yes there is. You can provide a thread factory.
ExecutorService threadPool = newFixedThreadPool(numThreads,
new ThreadFactory() {
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
As #matt b mentioned, another mechanism to ensure that the thread-pool is shutdown is to define a shutdown hook/listener in Tomcat.

How does the shutdown work in executors?

I have a ScheduledExecutorService and I do a task every 15 mins (in a web application in Tomcat).
In a ServletContextListener in contextDestroyed I have done:
Runtime.getRuntime().addShutdownHook(new Thread(){
#Override
public void run(){
scheduler.shutdown();
}
});
The scheduler is started like:
final Runnable r = new Runnable(){
#Override
public void run() {
System.out.println("My task");
//Do some task
}
};
updater.scheduleWithFixedDelay(r, 30, 15, TimeUnit.MINUTES);
Question:On shutdown any remaining task isn't executed.
There is a task running but I don't see any logs so it seems it is not executed. Why?
UPDATE:
If I start tomcat and then after 2 mins I shutdown then isn't the task considered as scheduled and must run? I mean if a task is submitted isn't it considered as pending? Or it must be actually running?
To explicitly wait until all running tasks are finished, do something like this:
try {
// Wait for one second indefinitively
while (!scheduler.awaitTermination (1, TimeUnit.SECONDS)) {
// wait until completion
}
} catch (final InterruptedException ex) {
// interrupted... you may log something
}
I can't quite parse your question but maybe your application is not exiting like you'd expect?
Shutting down an Executor will stop any tasks for being submitted but any running tasks will continue to run until they exit. From the shutdown() javadocs:
Initiates an orderly shutdown in which previously submitted
tasks are executed, but no new tasks will be accepted.
Invocation has no additional effect if already shut down.
If you edit your question to be more clear we can answer more appropriately.

If Quartz Scheduler dies, how do I stop the child Java processes that it started?

I'm currently using Quartz Scheduler as a replacement for Cron on our Windows 2003 Server Box.
I have two specific Jobs that needed to be started in a new VM, so I'm using the ProcessBuilder object in Java 5 to get my "Process" object.
The problem I'm running into is when our Quartz Scheduler JVM stops, the 2 jobs in separate JVM's keep going.
Process process = Runtime.getRuntime().exec(command);
try
{
while (true)
{
Thread thread1 = new Thread(new ReaderThread(process.getInputStream()));
Thread thread2 = new Thread(new ReaderThread(process.getErrorStream()));
thread1.start();
thread2.start();
thread1.join();
thread2.join();
Is there a way to Kill these threads when the parent JVM associated with my Quartz Scheduler dies? Even if I knew of a way to kill them from a different process manually, I could figure out how to do it through Quartz.
Thank you in advance
If the Quartz JVM exits normally, you can just destroy the processes in a finally block. This may obviate the need for a shutdown hook. A shutdown hook may not execute on abnormal JVM termination. The Runtime javadocs state,
If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.
Here is the modified code (I've added a timeout and a method call to wait for the process to exit)
private static final long TIMEOUT_MS = 60000;
Process process = Runtime.getRuntime().exec(command);
try
{
while (true)
{
Thread thread1 = new Thread(new ReaderThread(process.getInputStream()));
Thread thread2 = new Thread(new ReaderThread(process.getErrorStream()));
thread1.start();
thread2.start();
process.waitFor();
thread1.join(TIMEOUT_MS);
thread2.join(TIMEOUT_MS);
...
}
} finally {
process.destroy();
}
In general I've found that processes spawned from Java are clunky and not very resilient, as you've probably discovered given the need for the two ReaderThreads. In particular, subprocesses that freeze up can be difficult to terminate from within Java. As a last resort, you can use the Windows "taskkill" command to nuke the process from a command line or a scheduled task:
taskkill /IM MySpawnedProcess.exe
You can use a shutdown hook.
class ProcessKiller extends Thread {
private Process process = null;
public ProcessKiller(Process p) {
this.process = p;
}
public void run() {
try {
p.destroy();
} catch ( Throwable e ) {}
}
}
Runtime.getRuntime().addShutdownHook( new ProcessKiller( process ));

Categories