finalize() & dead-locks


I have some Qs regarding finalize() and dead-lock problems.
Q1: Is it always a bad thing to use synchronization (calling a synchonized
    function, or using a sychronized block) from the finalize() method?

My guess: If a thread A is inside semaphore SA and the GC is
          started. Then, the Finalizer-thread will be blocked if
          a finalize() method tries to enter SA.
          If the Finalizer-thread is blocked, fatal memory allocation
          problems will soon occurr.

Q2: In many cases (drivers etc) external resources are allocated.
    The only safe way to free them is inside the finalize() method.
    (The programmer using the lib may forget to free resources or an exception
     may occurr, so explicit deallocation of external resources is not
     safe enough. I believe JDBC implements a lot of finalize().)
    How do you write for example a database driver without synchronization?

Q3: If I define my own
       finalize() { f(); }
    How can I be sure that f() doesn't cause dead-lock?
    That f() is thread safe doesn't mean that it won't cause dead-lock.


Who is Participating?
vladi21Connect With a Mentor Commented:
just comment

Finalization of Class Instances
The class Object has a protected method called finalize; this method can be overridden by other classes. The particular definition of finalize that can be invoked for an object is called the finalizer of that object. Before the storage for an object is reclaimed by the garbage collector, the Java virtual machine will invoke the finalizer of that object.
Finalizers provide a chance to free up resources (such as file descriptors or operating system graphics contexts) that cannot be freed automatically by an automatic storage manager. In such situations, simply reclaiming the memory used by an object would not guarantee that the resources it held would be reclaimed.

The Java programming language does not specify how soon a finalizer will be invoked, except to say that it will happen before the storage for the object is reused. Nor does the language specify which thread will invoke the finalizer for any given object. If an uncaught exception is thrown during the finalization, the exception is ignored and finalization of that object terminates.

The finalize method declared in class Object takes no action. However, the fact that class Object declares a finalize method means that the finalize method for any class can always invoke the finalize method for its superclass, which is usually good practice. (Unlike constructors, finalizers do not automatically invoke the finalizer for the superclass; such an invocation must be coded explicitly.)

For efficiency, an implementation may keep track of classes that do not override the finalize method of class Object or that override it in a trivial way, such as

    protected void finalize() { super.finalize(); }

We encourage implementations to treat such objects as having a finalizer that is not overridden and to finalize them more efficiently.
The finalize method may be invoked explicitly, just like any other method. However, doing so does not have any effect on the object's eventual automatic finalization.

The Java virtual machine imposes no ordering on finalize method calls. Finalizers may be called in any order or even concurrently.

As an example, if a circularly linked group of unfinalized objects becomes unreachable, then all the objects may become finalizable together. Eventually, the finalizers for these objects may be invoked in any order or even concurrently using multiple threads. If the automatic storage manager later finds that the objects are unreachable, then their storage can be reclaimed.

eklasAuthor Commented:
Thanx vladi21.
The last ref to the bug was very useful.
All Courses

From novice to tech pro — start learning today.