守护线程
线程分为两种:普通线程和守护线程,在JVM启动时创建的所有线程中,除了主线程以外,其他的线程都是守护线程。(例如垃圾回收器和其他辅助工作线程)。当创建一个新线程时,新线程将继承创建它的线程的守护状态,因此默认情况下,主线程创建的所有线程都是普通线程。 普通线程与守护线程之间的差异仅在于当线程退出时发生的操作。当一个线程退出时,jvm会检查其正在运行的线程,如果这些线程都是守护线程,jvm会正常退出操作。当jvm停止时,所有任然存在的守护线程都将被抛弃——既不会执行finally代码块,也不会执行回卷栈,jvm直接退出。 应该尽可能的少使用守护线程——很少有操作能够在不进行清理的情况下被安全的抛弃。特别是,如果守护线程中执行可能包含I/O操作的任务,那么将是一种危险的行为。守护线程最好用于执行“内部”任务,例如周期性的从缓存中移除逾期的数据。
终结器 当不在需要内存资源时,可以通过垃圾回收器来回收,但对于其他一些资源,例如文件句柄或者套接字句柄 ,当不在需要他们时需要显示的交换给操作系统。为了实现这个功能,垃圾回收器对那些定义了 finalize 方法的对象进行特殊处理:在回收释放他们后,调用他们的 finalize 方法,从而保证一些系统资源被释放。 由于终结器可以在某个由jvm管理的线程中运行,因此终结器访问的任何状态都可能被多个线程访问,这样就必须对其访问操作进行同步。终结器并不能保证他们会在何时运行甚至是否会运行,并且复杂的终结器通常还会在对象上产生巨大的性能开销。要编写正确的终结器非常苦难(最好不要用)。在大多数情况下,通过使用 finally 代码块和显示的 close 方法,能够比使用终结器更好的管理资源,唯一例外的情况在于:当需要管理对象,并且该对象持有的资源时通过本地方法获得的。基于这些原因以及其他一些原因,我们要尽量避免编写或使用包含终结器的类。
在任务,线程,服务以及应用程序等模块中的生命周期结束问题,可能会增加他们在设计和实现时的复杂性。java并没有提供某种抢占式的机制来取消操作或者是终止线程。相反,它提供了一种协作式的中断机制来实现取消操作,但这要依赖于如何构建取消操作协议,以及能否始终遵守这些协议。通过使用FutureTask和Executor框架,可以帮助我们构建可取消的任务和服务。