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的源码,那些细节挺有意思的。

  • 相关阅读:
    Winform使用ML.NET时无法加载 DLL“CpuMathNative”问题的解决方法
    离线安装nuget包EPPlus
    码云上webide怎么提交
    EXCEL中自定义格式输入的数据怎么完整复制
    远程桌面剪贴板不好用了
    电脑里明明安装了net4.7但是VS里不显示?
    微信公众号里的音频怎么下载
    Hibernate-ORM:06.Hibernate中三种状态
    Hibernate-ORM:05.Hibernate中的list()和iterator()
    Hibernate-ORM:04.Hibernate中的get()和load()
  • 原文地址:https://www.cnblogs.com/trytocatch/p/2858331.html
Copyright © 2011-2022 走看看