How to force a java thread to close a thread local database connection

When using thread local database connection, the connection needs to be closed when the thread exists

I can do this only if I override the run () method of the calling thread Even if this is not a good solution, because when I exit, I don't know whether the connection has been opened by the thread

The problem is general: how to force the thread to call some finalization methods when the thread local object exits

I checked the source code of Java 1.5 and found that the thread local map is set to null, which will eventually lead to the garbage collection calling finalize (), but I don't want to count on the garbage collector

The following overrides seem inevitable to ensure that the database connection is closed:

@Override 
public void remove() {
    get().release(); 
    super.remove(); 
}

Release() closes the database connection, if it is already open But we don't know if the thread has ever used this thread's local If this thread does not call get (), it will consume a lot of energy here: ThreadLocal Initialvalue () will be called and a map will be created on this thread

Further clarification and examples based on thorbj ø RN's comments:

java. Lang. ThreadLocal is a factory type of objects bound to threads This type has getters and factory methods for objects (usually written by the user) When a getter is called, it calls the factory method only if it has never been called by this thread

Using ThreadLocal allows developers to bind resources to threads, even if the thread code is written by a third party

For example, we have a resource type named mytype. We want only one for each thread

Define in the usage class: private static ThreadLocal resourcefactory = new threadlocal() {@ override protected mytype initialvalue() {return new mytype();}}

Use local context in this course: public void somemethod() {mytype resource = resourcefactory. Get(); resource. Useresource();}

Get () can call initialValue () once in the lifecycle of the calling thread. At this point, the instance of mytype is instantiated and bound to this thread Then call get () through this thread to refer to this object again

The classic use example is when mytype is some thread unsafe text / date / XML formatter

However, such formatter usually does not need to be released or closed, database connection and I am using Java Lang. ThreadLocal each thread has a database connection

The way I see it, Java Lang. ThreadLocal is almost perfect Almost because if the calling thread belongs to a third-party application, there is no guarantee that the resource will be closed

I need your brain: by extending Java Lang. ThreadLocal I try to bind a database connection for each thread because it is exclusive - including threads that I cannot modify or overwrite I try to ensure that the connection is closed to prevent the thread from dying in an uncapped exception

When the normal thread exits, the garbage collector closes the connection (because mytype overrides finalize()) In fact, it happens quickly, but it's not ideal

If I have my way, then in Java There is another method in lang.threadlocal:

protected void release() throws Throwable {}

If this method exists in Java Lang. ThreadLocal, called by the JVM when any thread exits / dies, and then in my own overwrite, I can close my connection (the Redeemer will come to Zion)

Without this method, I am looking for another way to confirm the shutdown A method that does not rely on JVM garbage collection

thank you

Solution

If you are a sensitive disposition, look now

I don't expect this ratio to be good; It effectively doubles the number of threads in the system There may be some acceptable use cases

public class Estragon {
  public static class Vladimir {
    Vladimir() { System.out.println("Open"); }
    public void close() { System.out.println("Close");}
  }

  private static ThreadLocal<Vladimir> HOLDER = new ThreadLocal<Vladimir>() {
    @Override protected Vladimir initialValue() {
      return createResource();
    }
  };

  private static Vladimir createResource() {
    final Vladimir resource = new Vladimir();
    final Thread godot = Thread.currentThread();
    new Thread() {
      @Override public void run() {
        try {
          godot.join();
        } catch (InterruptedException e) {
          // thread dying; ignore
        } finally {
          resource.close();
        }
      }
    }.start();
    return resource;
  }

  public static Vladimir getResource() {
    return HOLDER.get();
  }
}

Better error handling, etc. as an exercise for implementers

You can also view the concurrent HashMap that tracks threads / resources and another thread polling isalive But the solution is a last resort to despair - objects may end up being checked too often or too little

I can't think of anything that doesn't involve instruments AOP may work

Connection pool will be my favorite choice

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>