How to force a Java thread to close a thread-local database connection

后端 未结 9 1108
鱼传尺愫
鱼传尺愫 2021-02-13 12:41

When Using a thread-local database connection, closure of the connection is required when the thread exists.

This I can only do if I can override the run() method of the

9条回答
  •  时光说笑
    2021-02-13 13:12

    Wrap your Runnable with a new Runnable with a

    try {
      wrappedRunnable.run();
    } finally {
      doMandatoryStuff();
    }
    

    construction, and let THAT be executed instead.

    You could even make it into a method, ex:

      Runnable closingRunnable(Runnable wrappedRunnable) {
        return new Runnable() {
          @Override
          public void run() {
            try {
              wrappedRunnable.run();
            } finally {
              doMandatoryStuff();
            }
          }
        };
      }
    

    and call that method passing in the runnable you're looking for.

    You may also want to consider using an Executor instead. Makes it much easier to manage Runable and Callables.

    If you do use an ExecutorService, you can use it like executor.submit(closingRunnable(normalRunnable))

    If you know that you'll be shutting down your entire ExecutorService and want connections to close at that point, you can set a thread factory which also does the close "after all tasks are done and shutdown called on the executor", example:

      ExecutorService autoClosingThreadPool(int numThreads) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(numThreads, numThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); // same as Executors.newFixedThreadPool
        threadPool.setThreadFactory(new ThreadFactory() {
          @Override
          public Thread newThread(Runnable r) {
            return new Thread(closingRunnable(r)); // closes it when executor is shutdown
          }
        });
        return threadPool;
      }
    

    In terms of whether or not doMandatoryStuff can know whether or not the connection was ever opened or not previously, one thing that comes to mind is having a second ThreadLocal that just tracks if it was opened or not (ex: when connection is opened, get then set an AtomicInteger to 2, at cleanup time, check to see if it's still at its default, say, 1...)

提交回复
热议问题