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.
Related
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
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.
I have a pipeline of tasks to be done on files, each different type of task runs inside a different executor service. After initilizing each executor service I start the first task, this is guaranteed to not finish until finished processing all files, as it processes a folder either no more work is required or its submits a callable task to service2. So when the shutdown() call on first task is sucessful all files will now be being processed in task2 or a another task further down the pipleline, and so on. When we can shutdown the final service then we have finished.
Loader loader = Loader.getInstanceOf();
List<ExecutorService> services = new ArrayList<ExecutorService>();
ExecutorService es = Executors.newSingleThreadExecutor();
//Init Services
services.add(es);
services.add(task1.getService());
services.add(task2.getService());
services.add(task3.getService());
services.add(task4.getService());
//Start Loading Files
es.submit(loader);
int count = 0;
for (ExecutorService service : services)
{
service.shutdown();
count++;
//Now wait for all submitted tasks to complete, for upto one day per task
service.awaitTermination(10, TimeUnit.DAYS);
MainWindow.logger.severe("Shutdown Task:" + count);
}
public class AnalyserService
{
protected String threadGroup;
public AnalyserService(String threadGroup)
{
this.threadGroup=threadGroup;
}
protected ExecutorService executorService;
protected CompletionService completionService;
protected void initExecutorService()
{
int workerSize = Runtime.getRuntime().availableProcessors();
executorService
= Executors.newFixedThreadPool(workerSize, new SongKongThreadFactory(threadGroup));
}
public ExecutorService getService()
{
if (executorService == null || executorService.isShutdown())
{
initExecutorService();
}
return executorService;
}
}
So this is all working fine Except Ive got my cpu load logic incorrect. Every service uses a pool equal to the number of cpus the computer has. So if computer has 4 cpus and we have 5 services then we could have 20 threads all trying to work at the same time overloading the cpus. I think I should in this case only have 4 threads at a time.
If I limited each service to use one thread then Id only have 5 threads runningat same time, but this still isnt right because
Will no longer be right if have more services or more cpus
Is inefficient, as the pipleline kicks of most of the work will be done by task1 , if I limit it to one cpu it will be slower than neccessary, conversly later on most of the threads will be done by later tasks and task1 will have nothing to do.
I think what I need is for all tasks to share one executor service, and set its poolsize equal to the number of cput the computer has. But then how am I going to identify when the service has finished ?
Im using Java 7, so is there anything in new in Java 7 that may help, currently just using Java 5 concurrency features
The core of your problem is: "[...] overloading the cpus."
If this is the problem, just schedule the priority of your application correctly. By the way, you are more likely to increase IO load than to increase CPU load; a lot of different threads is actually a good thing :-)
However, your question is: " But then how am I going to identify when the service has finished ? "
Very simple answer: submit() instead of invokeAll() and check the isDone() method of the Future object you receive.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable)
I have a requirement, that I want to start a poller once which will run foreever until the machine is restarted or the process is being killed. Now, I tried to start the poller from a main method using a shell script, but the problem is that as soon as the main method completed its execution, the poller also stoped working, as i am not using any servers to achieve so.
I heard something about daemon threads, but I am wondering how to create a daemon thread, which will run forever, and help my poller to run also.
UPDATE:
public class SomeThread extends Thread {
#Override
public void run() {
UnitPoller unitPoller = new UnitPoller();
unitPoller.doPolling();
}
public static void main(String[] args) {
SomeThread someThread = new SomeThread();
someThread.setDaemon(true);
someThread.start();
}
}
Above is my updated class, now whenever I execute this thread from the main method, it creates a thread but as soon as the execution of main method completes, my poller stops working, as the JVM shuts down.
With this problem, what should i do.
Thanks
You just create a thread and call th.setDaemon(true) before calling th.start().
Edit:
The above answers the question "how to create a daemon thread", but (as the scope of the question has changed), a proper answer would be: don't create a daemon thread if you want your thread to keep the JVM from exiting once the main thread completed.
1) You need someThread.setDaemon(false) instead of 'true'. A daemon thread actualy does NOT stop java from shutting down.
From the javadoc:
void java.lang.Thread.setDaemon(boolean on)
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
This method must be called before the thread is started.
2) I think it's not your main, but your run() method that finishes to soon. Try to put a while (true) loop around your doPolling method.
#Override
public void run() {
UnitPoller unitPoller = new UnitPoller();
while (true)
unitPoller.doPolling();
}
3) It's cleaner to call join() inside the main then to rely on daemon thread behavior.
try {
someThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
4) If you need a clean way to shut down the deamonthread. Consider implementing InterruptedException to exit the polling task. You can also use the shutdown hook.
The term "daemon thread" in Java is a bit misleading, as it really means "that thread is not supposed to keep the JVM alive". This means that the JVM will shut down as soon as the last non-daemon thread terminated (as you already stated in your question).
What you are possibly looking for is the Apache Commons Daemon project, which allows to create nice "system services", started through /etc/init.d/ entries and all. This works on Windows and *nix systems.
Using Java and App Server I deploy application that has a thread executer.
During un-deploy I request the executer to shutdown. This successfully cancels all the tasks. However via VisualVM I can still see a thread that represents the executer itself and it is in the wait sate. I don't keep any references to the executer as the whole application get undeployed. So if i repeat the deployment-undeployment cycle multiple times I can see how the threads number grows.
How do I get rid of them?
UPDATE:
code example
here is the code:
public void startScheduler()
{
if (scheduledExecutor == null)
{
scheduledExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("My ScheduledExecutor"));
processFuture = scheduledExecutor.scheduleAtFixedRate(new Runnable()
{
#Override
public void run()
{
startProcessor();
}
}, 0, 84600, TimeUnit.SECONDS);
}
}
public void stopScheduler()
{
if (processFuture != null)
{
processFuture.cancel(true);
processFuture = null;
}
if (scheduledExecutor != null)
{
try
{
scheduledExecutor.shutdownNow();
scheduledExecutor.awaitTermination(10, TimeUnit.SECONDS);
}
catch (InterruptedException ignored)
{}
finally
{
scheduledExecutor = null;
}
}
}
Could you please elaborate what you mean with "a thread that represents the executer itself". What is it's name/id/threadgroup? I don't think executor service creates such a thread.
Executors create new threads (using the configurable ThreadFactory). A Thread automatically inherits some properties of its parent, that is the Thread.currentThread(). The most problematic part of this behavior in a web application scenario with deploy/undeploy cycles however is the Thread's ContextClassLoader, which is inherited from the parent's thread. If your ContextClassLoader holds on to classes from within your web application archive, then the spawned Executors Thread will also have a reference to this ClassLoader. If the code which is executed by the Executor has e.g. ThreadLocals with classes from the WebappClassLoader, you may experience a ClassLoader leak problem.
The Executor needs to be stopped explicitly, using the method shutdown, otherwise it will hang around like you have found out. You can see from the javadoc for Executors.newSingleThreadExecutor that it includes a worker thread.
The javadoc for shutdownNow says:
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so if any tasks mask or fail to respond to interrupts, they may never terminate.
If the task being executed doesn't respond to interrupts (swallows InterruptedExceptions without ever exiting), then that would cause your executor to never get shutdown. Any non-daemon threads that don't get shutdown explicitly will hang around and keep the JVM from exiting. That can be a fun one to debug.