当私有实例变量超出范围时Java终止线程

Posted

技术标签:

【中文标题】当私有实例变量超出范围时Java终止线程【英文标题】:Java terminate Thread when private instance variable goes out of scope 【发布时间】:2015-12-18 12:23:05 【问题描述】:

我正在计划一个类,它可以动态打开与数据库的连接以存储一些设置。 如果在特定时间未使用或调用方法结束,该类应自动关闭连接。

到目前为止,这是我的解决方案,仅显示相关部分:

public class DBSettings 
    // ...
    private int ConnectionTimeout = 5000; 
    private ExecutorService Executor;
    private long LastTimeUsed;  
    // ...

    public DBSettings(DBConnection Conn) 
        Connection = new DBConnection(); // class handles Connection to Database
        // ...
    

    private void connect() 
        try 
            if (!Connection.isOpen()) 
                Connection.openConnection(DBUrl, DBUserName, DBPassword);
                LastTimeUsed = System.currentTimeMillis();
                Executor = Executors.newSingleThreadExecutor();

                Runnable closeRunnable = new Runnable() 
                    @Override
                    public void run()  
                        while (System.currentTimeMillis() < (LastTimeUsed + ConnectionTimeout)) 
                            try 
                                Thread.sleep(500);
                             catch (InterruptedException e)  
                        
                        disconnect(); 
                    
                ;

                Executor.submit(closeRunnable);
            
         catch (Exception e)  // ... 
    

    private void disconnect() 
        if (Connection!=null) 
            if (Executor!=null) 
                Executor.shutdown();
            
            Connection.closeConnection();
        
    

    public void setValue(String group, String key, String value) 
        // ...
        LastTimeUsed = System.currentTimeMillis();
    

ExecutorService 在 5 秒后正常停止并关闭连接。 但不幸的是,如果调用者方法结束,它至少会运行 5 秒。

我的测试程序:

private static void testDBSettings(DBConnection Conn) 
    // using my class
    DBSettings settings = new DBSettings(Conn);
    // set first value, open connection
    settings.setValue("Groupname", "Keyname", "Value");  
    Thread.sleep(1000);
    // set second value, extend connection lifetime
    settings.setValue("otherGroupname", "otherKeyname", "otherValue");  
    Thread.sleep(1000);
    // here is the problem: after "settings" goes out of scope my class should 
    // stop or terminate the ExecutorService without the need to call an extra method.

我阅读了很多关于 Threads 的信息,但找不到解决方案。

用 ScheduledExecutorService 尝试了另一种方法 - 结果相同。

finalize() 不起作用,因为它只被垃圾收集调用。

谁能帮帮我?

【问题讨论】:

你不会这样做。范围是一个编译时概念。 最好不要将变量名大写(就像你对private long LastTimeUsed;所做的那样),除非你定义了一个常量,在这种情况下你通常会使用全部大写。阅读起来可能会令人困惑。 为什么甚至像这样工作而不使用连接池?自己管理连接是浪费工作...... 您可以查看***.com/questions/2117783/… 我自己管理连接有一些原因:首先我必须同时支持多个数据库系统,使用不同的连接进行只读和读写,在多线程环境中运行...感谢您的回答,我现在正在考虑使用连接池。 【参考方案1】:

没有办法在 java 中跟踪这个。

你能做的最接近的是使用try-with-resource

try(MyClass myClass = new MyClass())
    myClass.doSomething();

 // Here myClass.close(); will be called.

【讨论】:

好的,我发现我的尝试行不通。在 MyClass() 中启动的线程只能由来自我的班级之外的额外代码终止。所以我会尝试使用上面提到的连接池。谢谢。

以上是关于当私有实例变量超出范围时Java终止线程的主要内容,如果未能解决你的问题,请参考以下文章

java线程安全问题之静态变量实例变量局部变量

java中静态成员变量、实例变量、局部变量何时创建、何时销毁?

java多线程之线程安全

一.对象及变量的并发访问

深入了解Java虚拟机java内存区域与内存溢出异常

为啥Java中的实例变量总是私有的?