I have a ExecutorService executor = Executors.newSingleThreadExecutor(); that i want to stop when the server is shutting down.
I have a class that implements ServletContextListener and it's annotated with #WebListener.
I have the two methods in that class:
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener started");
}
#Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
executor.shutdown();
executor.shutdownNow();
System.out.println("ServletContextListener destroyed");
}
And I see that it prints what's in both of them when it's supposed to, but when I press the stop button once in intelij, I get:
SEVERE: The web application [] appears to have started a thread named [pool-2-thread-1] but has failed to stop it. This is very likely to create a memory leak.
Right after it printed ServletContextListener destroyed.
I need to press the stop button again to fully stop it.
Why it doesn't shutdown the ExecutorService even though it reached the executor.shutdown();? What am I doing wrong?
PS: this is the only ExecutorService I have and no other threads are made by me.
EDIT2:
The executor service is a field in a singleton class, it's initialized with the class:
private ExecutorService executor = Executors.newSingleThreadExecutor();
This is how the class is initialized (lazy initialization):
public static RoomsManager getRoomsManager(ServletContext servletContext) {
if (servletContext.getAttribute(MANAGER_GAMES_ATTRIBUTE_NAME) == null) {
servletContext.setAttribute(MANAGER_GAMES_ATTRIBUTE_NAME, new RoomsManager());
}
return (RoomsManager)servletContext.getAttribute(MANAGER_GAMES_ATTRIBUTE_NAME);
}
And is annotated like this:
#WebListener
public class RoomsManager implements ServletContextListener {
The stop button is the red square near the play and debug buttons in intelij IDEA.
The problem is that you have two different RoomsManager instances (and hence, two different executors): first is created by Tomcat, and second is created by you.
When you annotate RoomsManager with #WebListener, Tomcat automatically creates an instance of that class and subscribes it to receive servlet context create/destroy events. That instance is the one that actually stops its executor and prints ServletContextListener destroyed.
The second instance is created by you in the getRoomsManager method (by the way, that method doesn't look thread-safe). That instance is not registered with Tomcat and doesn't receive servlet context "destroy" event, so it doesn't even try to shutdown its executor.
Doing this worked:
class YourThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
return new Thread(r, "Your name");
}
}
private ExecutorService executor = Executors.newSingleThreadExecutor(new YourThreadFactory());
Because apparently, the threads of tomcat are daemons, and therefore, when they create a new thread with return new Thread(r, "Your name"); it also becomes a daemon.
But in the DefaultThreadFactory that an executor service use, I saw that it makes sure daemonity of new threads is off.
That doesn't explain why executor.shutdown(); didn't work though, but now at least it properly shuts down.
Related
I have a number of Runnable tasks governed by an executor service.
These tasks are essentially JMS queue pollers and contain their own connections.
For example:
ExecutorService executor = Executors.newFixedThreadPool(...);
executor.submit(new MyListener());
My listener:
public class MyListener implements Runnable {
#Override
public void run() {
// Create my JMS connection here
}
}
How do I gracefully close the JMS connection in each task and then proceed to shutdown each thread?
I'm having problems shutting down the executor service with shutdown().
I need to force an interrupt with shutdownNow(), however, how can I be sure that my JMS connection has been closed without me explicitly calling .close()?
Is there an interface I'm missing that allows shutdown hooks to be executed when I attempt to stop the task?
Here's my solution to gracefully shutdown threads holding a connection, utilising the suggestion of an atomic boolean:
MyRunnable implements Runnable {
private volatile boolean isActive = true;
public void run() {
while(isActive && !Thread.currentThread().isInterrupted()) {
...
}
}
public void stop() {
isActive = false;
}
}
Main thread:
private void myShutdownHook() {
myRunnableInstance.stop();
// Can safely shutdown executor now...
}
The easiest would be to use an atomic boolean shared by the class that signals shutdown and the runnable. This tells them to stop. Another option is finding the threads yourself and interrupt them. You would need to catch the interrupted exception and close the connection. You can set the thread names when the runnable launch for easy id.
It is my first time to use Java Thread Pool for my new project, after I came across this
link http://www.javacodegeeks.com/2013/01/java-thread-pool-example-using-executors-and-threadpoolexecutor.html, I am more confused on this, here is the code from the page,
package com.journaldev.threadpool;
public class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s){
this.command=s;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName()+' Start. Command = '+command);
processCommand();
System.out.println(Thread.currentThread().getName()+' End.');
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public String toString(){
return this.command;
}
}
package com.journaldev.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimpleThreadPool {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread('' + i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println('Finished all threads');
}
}
in the code, a fixed size pool is created and 10 worker threads are created, am I right?
The thread pool is supposed to decrease the burden of a system, on the contrary, in the above code, I think it increases the burden by creating the pool in addition to the worker threads. why bother to use the thread pool?
Can anyone explain?
Thanks
I also read this post on StackOverflow
http://stackoverflow.com/questions/19765904/how-threadpool-re-use-threads-and-how-it-works
it did not help me either.
This is confusing because the Runnables are named WorkerThread, but they don't extend java.lang.Thread, they're just objects that implement Runnable. Implementing Runnable lets you specify a task that needs to be executed without having to instantiate an actual Thread object. The only threads created in your example are the main thread and the ones created by the Executor.
Note that, even if you change this code to make WorkerThread extend Thread, as long as the code doesn't call start on them it wouldn't result in more threads actually running. Constructing a thread object involves some things like checking with the Security Manager and initializing threadlocals, but it doesn't actually do anything at the OS-level to allocate a thread. As far as the Executor is concerned they're just Runnables, it would execute them using the threadpool's threads.
Bad example! The class called WorkerThread is not a thread, it is a "task".
The threads are hidden inside the ExecutorService. The example creates an ExecutorService with five "worker" threads, it creates ten tasks, it asks the executor service to "perform" them, and then finally, it waits for all of the tasks to be completed. It's totally up to the ExecutorService to decide how and when and in which worker thread to perform each task.
Another lesser problem with the example is how the main thread waits after asking the executor service to shut down. It spins, using CPU resources that maybe could have been used by one or more of the workers (depends on how many CPUs the host has available to run the various threads.) The wait loop should call Thread.yield() which gives up the main thread's time slice to any other runnable thread each time it is called.
I'm having a problem with closing my application because some threads are still running after I close the application.
Somebody can help me with some method to stop all Threads being executed in background before killing the main thread???
[EDITED]
With my questions about javafx I have noticed that many newer developers are facing problem managing Threads. I would like to share what I have done to simplify my life about managing threads on javafx. I've created an AsyncTask class based on AsyncTask from Android that basically do the same of Android's in a humble but effective way. You can find more information about it on Github project
You have three options here - the easiest is to simply create your Threads as deamons, which means that when your main program ends all deamon threads will terminate too.
Thread thread = new Thread();
thread.setDaemon(true);
Thats easiest, but the downside is that you wont get a graceful shutdown (ie the threads will stop, you wont get a chance to peform resource management etc, which may or may not be a problem for you).
The alternative is to keep a hold on the spawned threads and when your program receives the signal to close you iterate over the threads and pass in a signal of some sort to signa that they too should terminate
volatile boolean shutdown = false;
public void shutdown() {
shutdown = true;
}
public void run() {
while(!shutdown) {
... do your work here
}
... perform any cleanup work here
(Note: ignores any exception handling for clarity)
The last option is to use the Executor framework in java.util.concurrent
ExecutorService executorService = Executors.newFixedThreadPool(10);
... assign/invoke tasks etc
... at some point later your program is told to shutdown
... shutdown in executor too
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS); // wait for 10s in this case
executorService.shutdownNow();
Better way to fix this is add the EventHandler on Close Request:
#Override
public void start(Stage primaryStage) {
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent e) {
Platform.exit();
System.exit(0);
}
});
}
Override your Application Class
//System.exit(0) This will close all timers and threads inside the Jar application...
#Override
public void stop() throws Exception {
super.stop(); //To change body of generated methods, choose Tools | Templates.
System.exit(0);
}
Executors from the java.util.concurrent package are the way to go. Explicitly:
ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactory() {
#Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
Java 8 version with fixed ScheduledExecutorService
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, r -> {
Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setDaemon(true);
return thread;
});
The method Platform.exit() belongs to the JavaFX context.
When you call Platform.exit(), the method javafx.application.Application#stop() is called before the context terminates.
Put inside the stop() method everything that needs to be executed before the JavaFX context terminates.
With the System.exit(0) method, the application terminate abruptly.
This method is not secure because if at the moment you call System.exit(0) and a Job is still running, maybe executing a write in the database,
the application will not wait the Job fihish resulting in a corrupted database.
I have an application running JavaFX with SpringBoot and a thread pool. That is how I handle it.
//...
import javafx.application.Application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
#SpringBootApplication
public class Main extends Application {
ConfigurableApplicationContext context;
ScheduledExecutorService scheduledExecutorService;
#Override
public void init() {
this.context = SpringApplication.run(getClass());
this.context.getAutowireCapableBeanFactory().autowireBean(this);
this.scheduledExecutorService = Executors.newScheduledThreadPool(10);
}
#Override
public void stop() throws Exception {
super.stop();
this.context.close();
this.scheduledExecutorService.shutdownNow();
}
// ...
}
I'm developing a web application to be deployed onto Tomcat. When Tomcat is started, I use a servlet (in web.xml) to call a Java class:
<web-app>
<display-name>Consumer</display-name>
<servlet>
<servlet-name>start</servlet-name>
<servlet-class>com.test.sample.Consumer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
My Consumer.java subscribes to a queue on an AMQP server. I achieve this by using a while (true) loop, which works fine in a standalone Java program. Itt also works in the context of the web application, but I can never stop my Tomcat server (within my NetBeans IDE), and I believe that the while loop is the culprit. Here is some code:
public class Consumer {
public Consumer()
consume();
}
private void consume()
...
while (true) {
// Await incoming messages from queue
// Process message
}
}
}
Is there a better way to handle this? Or to signal a stop to break out of the loop?
Thanks!
Updated to use ServletContextListener:
public final class ApplicationListener implements ServletContextListener {
private ScheduledExecutorService scheduler;
public ApplicationListener() {
}
#Override
public void contextDestroyed(ServletContextEvent event) {
System.out.println("***** Stopping Consumer *****");
scheduler.shutdownNow();
}
#Override
public void contextInitialized(ServletContextEvent event) {
System.out.println("***** Starting Consumer *****");
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new ScheduledConsumer(), 0, 15000, TimeUnit.MILLISECONDS);
}
public class ScheduledConsumer implements Runnable {
#Override
public void run() {
Consumer k = new Consumer();
k.consumeOnce();
}
}
}
I have some suggestions, but they require that you modify your architecture a bit in order to more nicely play with your container environment.
Servlet containers support "listeners" that can get notification of various events. Specifically, one of them is the ServletContextListener which gets notified when the context (aka. webapp) is being brought into service (via the contextInitialized method) and when it is being brought out of service (via the contextDestroyed method).
My recommendation would be to do the following:
Change your Consumer class's constructor so that it does not automatically call consume(); instead, add a public method like consumeOnce and don't use a loop at that level at all
Write a ServletContextListener that has a Consumer and a Thread reference as members as well as a volatile boolean stop flag; in contextInitialized it should create a new Consumer object, then launch a new (daemon) thread that:
Calls Consumer.consumeOnce
Calls Thread.sleep for an appropriate amount of time
Loops over the previous 2 steps until the stop flag is true
Have your ServletContextListener's contextDestroyed method set the stop flag to true and call Thread.interrupt on the running thread.
I'm sure I'm missing some exact details, but that's the general idea. When Tomcat shuts down, your code will be notified of the shutdown and you can cleanly terminate your own looping-thread. You may need to provide a way for the Consumer to abort an attempt to consume whatever it consumes (e.g. stop waiting to pull an object from an empty queue) if it doesn't abort when it gets a Thread.interrupt signal. (For instance if you use an Object.wait() in order to wait for a monitor notification, then you'll want to change that so it uses a wait with a timeout so that you won't block forever).
You have to place the code with the loop in a different thread and start the thread from your consumer.
private void consume() {
Thread x = new Thread(new Runnable() {
#Override
public void run() {
while(true) {
....
}
});
x.start();
}
My Tomcat 7 is reporting that there may be a memory leak in my webapp
SEVERE: The web application [/mywebapp] appears to have started a
thread named [pool-1-thread-1] but has failed to stop it. This is
very likely to create a memory leak.
I have a long running task in my webapp that gets initialized when the webapp is started.
public class MyContextListener implements ServletContextListener{
Scheduler scheduler = null;
public MyContextListener(){
scheduler = new Scheduler();
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
scheduler.stop();
}
#Override
public void contextInitialized(ServletContextEvent arg0) {
scheduler.start();
}
}
.. and my Scheduler.java
public class Scheduler {
private final ScheduledExecutorService fScheduler;
public Scheduler() {
fScheduler = Executors.newScheduledThreadPool(1);
}
public void start(){
fScheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
//Perform some task
}
}, 1, 240, TimeUnit.MINUTES);
}
public void stop(){
fScheduler.shutdownNow();
}
}
Even though I calling scheduler.stop(); when shutting down the server, its still reporting there could be a memory leak.
This app is deployed on jelastic.com and I find that once it is started, it runs well for around two days and then the tasks don't seem to be running. There is no exceptions or errors in the logs too.
Am I doing anything wrong here ? Is there really a potential memory leak ?
Calling fScheduler.shutdownNow(); is not enough:
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks.
From JavaDoc.
Instead you must explicitly wait for the tasks that are currently running:
fScheduler.shutdownNow();
fScheduler.awaitTermination(10, TimeUnit.SECONDS);
I believe you should not call the shutdown from the Listener but from the Servlet directly.
contextDestroyed() of the listener is too late for the executor service. As stated in the javadoc All servlets and filters will have been destroyed before any ServletContextListeners are notified of context destruction.
whereas overriding the servlet destroy() should be OK as according to the javadoc This method gives the servlet an opportunity to clean up any resources that are being held (for example, memory, file handles, threads...
#Override
public void destroy( ) {
fScheduler.shutdownNow();
fScheduler.awaitTermination(10, TimeUnit.SECONDS);
super.destroy( );
}