后台线程的突然结束
当所有的非后台线程终止后后台线程都被突然结束当后台线程创建了一些全局资源(例如一个数据库连接或一个临时文件)而后台线程结束时这些资源没有被关闭或删除就会导致问题
对于这个问题我建议制定规则使 Java 虚拟机在下列情况下不关闭应用程序有任何非后台线程正在运行或者 有任何后台线程正在执行一个 synchronized 方法或 synchronized 代码块
后台线程在它执行完synchronized 块或 synchronized 方法后可被立即关闭
重新引入stop() suspend() 和 resume() 关键字
由于实用原因这也许不可行但是我希望不要废除stop() (在 Thread 和 ThreadGroup 中)但是我会改变 stop() 的语义使得调用它时不会破坏已有代码但是关于 stop() 的问题请记住当线程终止后 stop() 将释放所有锁这样可能潜在地使正在此对象上工作的线程进入一种不稳定(局部修改)的状态由于停止的线程已释放它在此对象上的所有锁所以这些对象无法再被访问
对于这个问题可以重新定义stop() 的行为使线程只有在不占有任何锁时才立即终止如果它占据着锁我建议在此线程释放最后一个锁后才终止它可以使用一个和抛出异常相似的机制来实现此行为被停止线程应设置一个标志并且当退出所有同步块时立即测试此标志如果设置了此标志就抛出一个隐式的异常但是此异常应不再能被捕捉并且当线程结束时不会产生任何输出注意微软的 NT 操作系统不能很好地处理一个外部指示的突然停止(abrupt)(它不把 stop 消息通知动态连接库所以可能导致系统级的资源漏洞)这就是我建议使用类似异常的方法简单地导致 run() 返回的原因
与这种和异常类似的处理方法带来的实际问题是你必需在每个synchronized 块后都插入代码来测试stopped标志并且这种附加的代码会降低系统性能并增加代码长度我想到的另外一个办法是使 stop() 实现一个延迟的(lazy)停止在这种情况下在下次调用 wait() 或 yield() 时才终止我还想向 Thread 中加入一个 isStopped() 和 stopped() 方法(此时 Thread 将像 isInterrupted() 和 interrupted() 一样工作但是会检测 stoprequested的状态)这种方法不向第一种那样通用但是可行并且不会产生过载
应把suspend() 和 resume() 方法放回到 Java 编程语言中它们是很有用的我不想被当成是幼儿园的小孩由于它们可能产生潜在的危险(当被挂起时一个线程可以占据一个锁)而去掉它们是没有道理的请让我自己来决定是否使用它们如果接收的线程正占据着锁Sun 公司应该把它们作为调用 suspend() 的一个运行时间异常处理(runtime exception)或者更好的方法是延迟实际的挂起过程直到线程释放所有的锁
被阻断的 I/O 应正确工作
应该能打断任何被阻断的操作而不是只让它们wait() 和 sleep() 我在 Taming Java Threads 的第二章中的 socket 部分讨论了此问题但是现在对于一个被阻断的 socket 上的 I/O 操作打断它的唯一办法是关闭这个 socket而没有办法打断一个被阻断的文件 I/O 操作例如一旦开始一个读请求并且进入阻断状态后除非到它实际读出一些东西否则线程一直出于阻断状态既使关掉文件句柄也不能打断读操作
还有程序应支持 I/O 操作的超时所有可能出现阻断操作的对象(例如 InputStream 对象)也都应支持这种方法
这和 Socket 类的setSoTimeout(time) 方法是等价的同样地应该支持把超时作为参数传递到阻断的调用
ThreadGroup类
ThreadGroup应该实现 Thread 中能够改变线程状态的所有方法我特别想让它实现 join() 方法这样我就可等待组中的所有线程的终止
总结
以上是我的建议就像我在标题中所说的那样如果我是国王我希望这些改变(或其它等同的方法)最终能被引入 Java 语言中我确实认为 Java 语言是一种伟大的编程语言但是我也认为 Java 的线程模型设计得还不够完善这是一件很可惜的事情但是Java 编程语言正在演变所以还有可提高的前景
[] [] [] [] [] [] []