zoukankan      html  css  js  c++  java
  • swing程序的关闭机制看好你的swing.Timer,别让它成为程序不能退出的原凶

      java中常见的Timer有两个,一个是javax.swing.Timer,另一个是java.utl.Timer,两者的功能大同小异,最主要的差别在于swing.Timer的任务是放到EDT线程中执行的,可以很方便地进行swing的UI操作,另外swing.Timer是一个守护线程,utl.Timer则是可以设置是否为守护线程。

      JVM中有这样一个规定,如果非守护线程都退出了,那么JVM会关闭,不管是否还有守护线程在运行。

      swing程序的关闭机制:在swing程序中,EDT线程负责处理事件,它是一个非守护线程;另外有一个名为AWT-Shutdown的非守护线程,负责在所有窗口都关闭后,关闭EDT线程,然后自己退出,所以正常情况下,窗口都关闭时,程序是会自动退出的(不是调用System.exit)。

      前不久在项目中碰到个问题,我使用了一个循环执行的Timer后(以下均指javax.swing.Timer),窗口全关闭后程序也不退出了(窗口全关闭后,如果再没有非守护线程,虚拟机应该是会自动退出的),后来我把timer的周期改为了1000+毫秒,程序就能退出了,小于1000就无法退出。之后经过调试跟踪,了解了swing的关闭机制,而且注意到,在窗口都关闭时,AWT-Shutdown它并不是立即关闭EDT线程,而是mainLock.wait1000毫秒,然后再次检查关闭条件(还会检查EDT中是否有任务正在执行),如果不符合,就继续寻找关闭的时机,循环此过程,所以,如果timer的间隔小于1000,主意味着,AWT-Shutdown在waait的1000毫秒中,又有新的任务被放到EDT任务队列中,当AWT-Shutdown醒来时,关闭条件又不符合了,所以,如果你的timer间隔小于1000,将造成AWT-Shutdown不能关闭EDT,程序无法退出,说到这里,可能大家也明白了,并不只是timer,使用SwingUtilities.invokeAndWait、invokeLater、SwingWorker等,都会有此问题。

      有兴趣的朋友可以阅读下AWTAutoShutdown的源码,那些细节挺有意思的。

  • 相关阅读:
    git 重命名文件夹
    关于IDEA的Incoming窗口的问题
    mysql替换字段中部分字符串
    IDEA项目改包名改项目名并启动【我】
    IDEA在自带市场安装黑色主题及调整包管理器字体大小【我】
    解决Invalid bound statement (not found)(Mybatis的Mapper绑定问题)
    java中Date日期类型的大小比较
    MyBatis-Plus Wrapper条件构造器查询大全
    idea黑色主题
    python3安装mysqlclient,解决django使用pymysql报错的问题
  • 原文地址:https://www.cnblogs.com/trytocatch/p/2858331.html
Copyright © 2011-2022 走看看