Thread.stop: call-stack does unwind normally

November 19, 2006

Abstract

The Thread.stop method is deprecated and calling this method could lead to problems. However, it appears that my understanding of the stop mechanism was incorrect; the stopping thread unwinds the call-stack normally, instead of stopping on the spot.

Introduction

I’m preparing a presentation about low level concurrency issues, like monitor-locks and the wait/notify mechanism. I’m going to give this presentation on November 28 at Xebia: the company I work for.

One of the the issues I’m going to discuss is the Thread.stop method and why it is deprecated. But after refreshing my memory, by (re)reading the documentation, I gained a renewed insight about this matter and although it doesn’t change anything about the fact that the stop methods shouldn’t be used, I find it interesting enough to blog about. This also helps me to make sure, I won’t forget it.

Old (and incorrect) understanding

My old understanding was this: when a thread sees that the Thread.stop method was called, it stops processing other instructions and dies. The problem with this stopping mechanism, is that a thread has no chance to do clean-ups like:

  • executing finally blocks or exception handlers
  • releasing monitor-locks: the locks are obtained when entering a synchronized statement (or method). Normally these are transparently released, when the thread exits the critical section.

Example with not executed finally block:

Connection con = connectionPool.take();
try{
   ..while executing this part, the thread is stopped.
}finally{
   connectionPool.return(con);
}

In this example the connection is not returned to the pool because the finally block is not run.

Example with a synchronized block:

synchronized(someobject){
    ..while executing this part, the thread is stopped
}

In this example the lock is not returned, because the release of that lock, when the thread exits the synchronized block, is not executed. I thought the lack of releasing locks, and other resources, caused by the abrupt termination of the thread, is the reason why the stop method is deprecated.

Renewed understanding

But I realized this understanding wasn’t correct, after reading the following document ‘Why Are Thread.stop, Thread.suspend,
Thread.resume and Runtime.runFinalizersOnExit Deprecated?
‘. The first thing that was different from what I expected, was that all monitor-locks are released when a thread is stopped. How is this realized? Is a special end-of-life task being executed by the Java virtual machine, or operating system, when a thread is stopped?

Luckily the Thread.stop method doesn’t rely on a special mechanism to release those locks; it uses the normal exception mechanism to unwind the call-stack. When the stop method is called, the receiving thread will throw a ThreadDead error, regardless of what is was doing. As soon as this exception (technically it’s an Error) is thrown, the thread is able to unwind the call stack; giving all finally blocks and exception handlers chance to execute. The ThreadDead exception normally is not caught (and possibly discarded), because it is an java.lang.Error. This allows a thread to unwind the call-stack completely, so it can die. This means that all resources can be returned; monitor-locks are released and database connections are returned the connection pool.

Why is Thread.stop deprecated

The reason why the Thread.stop method is deprecated, is that all monitor-locks are released when the call-stack is unwound. This leaves the objects, protected by these monitor-locks, probably in an inconsistent state. This means that other threads can access these damaged objects. Preventing this problematic behavior is simple: don’t use the Thread.stop method. If you want to know how to stop a thread, I recommend reading the section ‘What should I use instead of Thread.stop?’ in the earlier provided document or reading ‘Java Concurrency in Practice‘.


Interface-methods vs util-methods

November 11, 2006

Abstract

Do methods belong in an interface or in a utility class? This post describes my vision about this question.

Introduction

A few weeks ago there was a discussion on a blog about the oo’ness of utility classes. Some people claimed that utility classes are not object oriented, because the static utility method is not executed on the object itself. Instead, this object is passed as an argument to a utility-method. I think this view limits good oo-design, because calling someObject.someMethod() is not the holy grail of object oriented programming (just like subclassing).

2 Different types of methods

For this discussion I distinguish 2 different types of methods:

  1. implementation dependent methods like List.size(). The size method depends on a specific implementation of the List interface, how it is determined; maybe an internal counter is used, maybe an iteration over the elements of the list is done.
  2. implementation independent methods. These methods are build on top of other interface methods, without having any implementation specific knowledge. An example of such a method is the List.indexOf(Object). This method can use the List.get(int) and the List.size() methods to find the first index. There is not always a clear separation which methods are dependent and which ones are not; you could always create a List implementation where the indexOf method uses a hashtable for better search-performance.

Possible locations

The best location for an implementation dependent method is adding it to the interface. If it is placed outside that interface, you would have to break encapsulation, and in most cases this is something you want to prevent. The implementation independent method has more options of being placed:

  1. add them to the interface. An example is the already mentioned List.indexOf(Object) method. A technique often used, is creating an abstract super class that contains the implementation independent methods. The subclass only needs to implement the implementation dependent methods. An example of this technique is the AbstractList and the ArrayList. The ArrayList extend the AbstractList and only needs to implement the implementation dependent methods like get(int) and size().
  2. add them to a utility class. An example is the Collection.sort(List)

Which location is best

The question remains which location is best. Like most interesting questions, there is no black and white answer. If you add a new method to an interface, it could be that you are breaking implementing classes; especially when the interface is very public and you don’t have control over the implementations. Although using an abstract superclass can prevent some damage, you have no way of knowing if a class implements the interface directly.

Methods in utility classes don’t have this problem, because adding a new utility-method won’t break any implementations. Another important advantage of using a utility class is that it helps to prevent bloated interfaces. You can even use multiple utility classes to group related methods. I must confess that this technique is not something I have used very often, but on certain occasions it was very helpful. But utility classes are not without problems either; they are more difficult to use because it is less obvious where functionality can be found. The lack of code completion for these methods doesn’t help either. The last disadvantage I can think of is that they can’t make use implementation specific functionality.

Which location is best, needs to be decided on a case by case basis. But in a lot of cases interfaces are quite simple and adding new methods to the interface is often the easiest solution.


JMX and concurrency problems

November 9, 2006

Abstract

In this entry I try to explain that introducing Java Management Extensions (JMX) requires some additional care for concurrency control. If JMX is added without extra care, the system could be subject to all kinds of concurrency related problems like data races and visibility problems.

Introduction

A few months ago I was working on an existing batch application and sometimes strange problems occurred: a process was throwing strange runtime exceptions (like ArrayIndexOutOfBoundsException and NullPointerException). The confusing thing was that everything was (unit)tested very heavy and the tests didn’t rapport any exceptions.

After a deeper inspection we figured out that the process was running concurrently (so multiple instances of that process were running at the same time) and that process was reading and writing to a data structure. The consequence of the concurrent execution was that the data structure got corrupted and that caused the exceptions to be thrown. The strange thing was that this process should not be able to run concurrently. It was executed by Quartz (and wired up in Spring) and by making the job stateful, concurrent execution should be impossible.

After a while I found the cause of the problem: the process was not only executed by Quartz, but also by a JMX client. The MBean (acting in behalf of the JMX client) bypassed the Quartz mechanism completely and just called the process method on the service. The fix was quite easy: instead of calling the method directly, the Quartz scheduling mechanism should be used to schedule the task for immediate execution.

The bigger problem

The bigger problem is that JMX is added into a system without realizing that ‘components’ are now used in a multithreaded environment. The consequence is you will get into all kinds of concurrency related problems like dataraces and visibility problems. Even the most simplest case: setting a property on a component is not without problems if the property isn’t volatile or used in a synchronized context (final also is a perfect but under appreciated way to prevent these problems).

Conclusion

The bottom line is that adding JMX to a system is not something that should be thought of lightly. The fact that certain environments (like Spring) make it very easy to JMX-ify beans, doesn’t mean you should forget about your responsibilities.