In my webapp I have 3 threads where tomcat fails to stop 2 of these on reload.
SEVERE: The web application [/myapp] appears to have started a thread named [Thread-8] but has failed to stop it. This is very likely to create a memory leak.
mai 08, 2013 11:22:40 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
This causes the CPU usage to rise for each reload.
Here is one of the threads that tomcat fails to stop:
Some of the code implemented in my ServletContextListener:
public void contextInitialized(ServletContextEvent event)
{
final UpdaterThread updaterThread = new UpdaterThread();
updaterThread.start();
event.getServletContext().setAttribute("updaterthread", updaterThread);
}
public void contextDestroyed(ServletContextEvent event)
{
UpdaterThread updaterThread = (UpdaterThread) event.getServletContext().getAttribute("updaterthread");
if (updaterThread != null)
{
updaterThread.stopUpdater();
updaterThread.interrupt();
updaterThread = null;
}
}
And the important parts of UpdaterThread:
public class UpdaterThread extends Thread implements Runnable
{
private boolean alive = true;
#Override
public void run()
{
while(true)
{
try
{
while (alive)
{
doUpdate();
sleep(60*1000);
}
}
catch (InterruptedException ie) {}
catch (Exception e) {}
}
}
public void stopUpdater()
{
alive = false;
}
}
Does anyone have any idea why this thread don't stops? Is there a better way to implement a thread doing some work at specific times?
As far as I can see, you're not actually stopping your thread at all. You have two while loops, and you only stop the inner when you set alive = false. The outer will run forever, doing nothing. You also don't handle the interrupt your sending, so that won't terminate the thread either.
I would instead do something like this:
public void run()
{
while(alive)
{
try
{
doUpdate();
sleep(60*1000);
}
catch (InterruptedException ie) {
alive = false;
}
}
}
Also, if you give your thread a proper name when creating it, you'll see if it's actually that thread that is causing the problem Tomcat is reporting.
it’s related to ThreadLocal issues with tomcat, Check this document
http://wiki.apache.org/tomcat/MemoryLeakProtection
Mar 16, 2010 11:47:24 PM org.apache.catalina.loader.WebappClassLoader
clearThreadLocalMap SEVERE: A web application created a ThreadLocal
with key of type [test.MyThreadLocal] (value
[test.MyThreadLocal#4dbb9a58]) and a value of type [test.MyCounter]
(value [test.MyCounter#57922f46]) but failed to remove it when the web
application was stopped. To prevent a memory leak, the ThreadLocal has
been forcibly removed.
http://forum.springsource.org/showthread.php?84202-Installation-ThreadLocal-forcefully-removed
A Small change in your code to fix this issue
public class UpdaterThread extends Thread implements Runnable
{
private boolean alive = true;
#Override
public void run()
{
while(alive)
{
try
{
doUpdate();
sleep(60*1000);
}
catch (InterruptedException ie) {
//sleep interrupted
}
catch (Exception e) {
// exception in doUpdate method ? must handle this
}
}
}
public void stopUpdater()
{
alive = false;
}
}
However, Sleep in while loop likely to create a performance issue. You could use Thread.sleep only if you want to suspend your thread for some time. Do not use it if you want to wait for some condition.
Check this SO question : Thread-sleep-called-in-loop
Related
I have the next code:
Executor exe = Executors.newFixedThreadPool(20);
while (true) {
try {
exe.execute(new DispatcherThread(serverSocket.accept()));
continue;
} catch (SocketException sExcp) {
System.exit(-1);
} catch (Exception excp) {
System.exit(-1);
}
}
For each DispatcherThread I create a connection to the database (it means I have 20 connections), what I need to know is how I can close the connection to the database when the thread is stopped or it stops or finishes its flow.
You cannot directly know when the thread is stopped, the closest thing you have is Thread#isAlive method but it may return false when the run method in the thread has finished but the thread may not be stopped since the JVM cannot guarantee it. But if your DispatcherThread class implements Runnable interface then you can write the clean up at the bottom of the run method.
Skeleton code:
class DispatcherThread implements Runnable {
#Override
public void run() {
try {
//open database connection an such...
//...
//handle the work here...
} catch (...) {
//ALWAYS handle the exceptions
} finally {
//cleanup tasks like close database connection
}
}
}
By the way, Thread suffix is not a good name for a class that technically is not a thread (because it doesn't extend from Thread). Instead, give a proper name according to what should do.
You could close the thread-specific connection at the end of your run() method.
A finally block would ensure that it happened however the run() method exited.
class DispatcherThread extends Runnable {
public void run() {
...
try {
...
}
finally {
// Close the connection
}
}
I want to sandbox an application where end users can submit Java code to a server where it is compiled and executed (kind of a web-based IDE as part of an educational game). Most aspects can easily be handled by using either the standard security manager or verification of used APIs against a whitelist using ASM or similar.
An open problem is how to deal with infinite loops. As threads have their own stack, StackOverFlowErrors seem to be thread-local. I have done a little spike and came up with this:
public class TryToSurviveAStackOverflow {
public static void main(String[] args) throws Exception {
final Runnable infiniteLoop = new Runnable() {
#Override public void run() {
run();
}
};
Runnable sandboxed = new Runnable() {
#Override public void run() {
try {
Thread.sleep(10000); // some time to connect VisualVM to monitor this
infiniteLoop.run();
}
catch (StackOverflowError x) {
System.err.println("Thread crashed with stack overflow");
} catch (InterruptedException e) {
System.err.println("Thread interruped");
}
}
};
Thread thread = new Thread(sandboxed,"infinite loop");
thread.start();
thread.join();
System.out.println(thread.getState());
System.out.println("I am still alive");
}
}
This seems to work, but how safe is this? In particular, what happens to the stack space used by the unsafe thread? I can see that the state of the thread is set to TERMINATED.
Any help / pointers are highly appreciated !
Cheers, Jens
If an uncaught exception is thrown and you want to recover by restarting an identical thread to the one the exception was just thrown in (e.g JMS connection lost), what's the easiest way?
The class extends from Thread, and the thread has an UncaughtExceptionHandler.
The easiest thing to do is to "restart" the current thread via the run() method
void run() {
boolean done = false;
while(!done) {
try {
...
done = true;
} catch (ConnectionLostException ex) {
// log exception
}
}
}
I am starting two thread one after the other.
The first thread is reading in a loop from input and the other one check some condition in a loop to
sent an interrupt to the other.
The problem is that any thread of the two I start first it doesnt let the other stop.
If i start reading in never runs the other thread until it finishes and if I start the other thread is checking the condition in the loop and it wont move forward in code until the condition is true and gets out of the loop.
What is the correct way to do it?
Sample code below:
Thread 1)
public class InterruptionThread extends Thread {
public void run() {
while (condition not true) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (condition true) {
do some work
return;
}
}
}
Thread 2)
public class ReadingThread extends Thread{
public void run() {
int input;
while (true) {
try {
input = stdInput.read();
} catch (IOException e) {
e.printStackTrace();
return;
}
System.out.print((char) input);
}
}
}
This sounds like you are not starting the threads in a correct manner.
Use the start() method to start threads, not the run() method (which doesn't actually start a thread).
new InterruptionThread().start();
new ReadingThread().start();
I think your problem is of producer consumer problem type.
So would suggest you to use BlockingQueue.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
Also instead of directly handling threads; it will be easy if you use Executor Framework; this way thread management will become pretty easy.
I have an application that every 15 minutes or so does a replication from a remote database. It just keeps the two repositories in sync. Once this replication is going it is not possible to do it again. I have setup the following structure but I'm not sure if it is the correct approach.
public class ReplicatorRunner {
private static Lock lock = new ReentrantLock();
public replicate() {
if (lock.tryLock()) {
try {
// long running process
} catch (Exception e) {
} finally {
lock.unlock();
}
} else {
throw new IllegalStateException("already replicating");
}
}
}
public class ReplicatorRunnerInvocator {
public void someMethod() {
try {
ReplicatorRunner replicator = new ReplicatorRunner();
replicator.replicate();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
The ReplicatorRunner is the class owning the method replicate which can only be run one at a time.
Edit.
I need the next call to fail (not block) if the method is already running on any instance.
This looks good. ReentrantLock.tryLock() will only give the lock to one thread, so synchronized is not necessary. It also prevents the blocking inherent in synchronization that you say is a requirement. ReentrantLock is Serializable, so should work across your cluster.
Go for it.
Change public replicate() to public synchronized replicate()
That way replicate will only ever allow access to one thread at a time. You'll also be able to delete the ReentrantLock and all associated code.
I ended up using the following:
public class ReplicatorRunner {
private static Semaphore lock = new Semaphore(1);
public replicate() {
if (lock.tryAcquire()) {
try {
// basic setup
Thread t = new Thread(new Runnable() {
public void run() {
try {
// long running process
} catch Exception (e) {
// handle the exceptions
} finally {
lock.release();
}
}
})
t.start();
} catch (Exception e) {
// in case something goes wrong
// before the thread starts
lock.release();
}
} else {
throw new IllegalStateException("already replicating");
}
}
}
public class ReplicatorRunnerInvocator {
public void someMethod() {
try {
ReplicatorRunner replicator = new ReplicatorRunner();
replicator.replicate();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
Without looking at the specifics of the ReentrantLock, it occurs to me that this prevention of multiple simultaneous replication routines will be limited to a single JVM instance.
If another instance of the class is kicked off in a separate JVM, then you might be in trouble.
Why not put a lock mechanism on the database? i.e. A row in a control table that is set to a value depicting whether or not the replication is busy running, and reset the value when the replication is finished.
take a look at the Semaphore class here or mark the method as synchronized
the thread executing the method at any given time owns a lock on it avoiding other threads to call the method until its execution ends.
Edit: if you want the other threads to fail, you could use a Lock, and test if the lock is avaible by the tryLock method.