免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 19694 | 回复: 11
打印 上一主题 下一主题

如何让被阻塞的线程销毁? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-06-19 19:24 |只看该作者 |倒序浏览
一个线程内部使用一个循环实现线程的存在。并使用一个开关变量来控制循环是否终止,从而实现一个线程是否结束。但是,当循环内部存在一个等待资源的方法,如果没有一定的资源,方法一直阻塞。由于方法的阻塞,使得即使控制循环的开关变量已经为false,但程序一直阻塞在方法上,一直都没有去判断循环是否已经可以结束。使得线程无法退出销毁?

private boolean isRunning = true;

public run(){

while(isRunning)
.....

f1();//该方法一直阻塞,等待获取某种资源,如果在等待过程中,isRunning = false;但由于f1()的阻塞,而使循环无法结束。线程也就无法结束。但等待获取的资源有可能永远得不到。这样线程就无法停止。

.....

}


有哪位高手可以解决上述问题?谢谢!

[ 本帖最后由 hzx317 于 2006-6-19 19:26 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-06-19 23:39 |只看该作者
很多数据库都有死锁检测线程,也就是单独的一个用于处理死锁的线程。可为每个启动的线程设置一个计数器,每循环一次加一,监控线程每隔一定的时间间隔对这些线程的计数器来一个快照并判断线程的循环是否正在运行,如果没有,杀之!

[ 本帖最后由 apollolegend 于 2006-6-19 23:41 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2006-06-20 00:29 |只看该作者
while(isRunning)
{
...
}

是Sun推荐的做法,至于阻塞,我通常采取的做法是 task.interrupt();

论坛徽章:
0
4 [报告]
发表于 2006-06-20 09:30 |只看该作者

回复 2楼 apollolegend 的帖子

知道了哪个线程是死的,又什么停了它呢?前面已经说过,线程一直阻塞在f1()方法。根本没机会去判断     “isRunning”是true还是false?

论坛徽章:
0
5 [报告]
发表于 2006-06-20 09:36 |只看该作者
线程一直阻塞在f1()方法
丑陋的解决办法:调用前先存个时间,另外一个线程检测一下不就ok

论坛徽章:
0
6 [报告]
发表于 2006-06-20 16:30 |只看该作者

回复 5楼 ua 的帖子

可否说具体些,给你句柄之后。如何销毁一个对象(实例)?

论坛徽章:
0
7 [报告]
发表于 2006-06-21 18:36 |只看该作者
原帖由 hzx317 于 2006-6-20 09:30 发表
知道了哪个线程是死的,又什么停了它呢?前面已经说过,线程一直阻塞在f1()方法。根本没机会去判断     “isRunning”是true还是false?

我不是已经告诉你可以用interrupt()来解除阻塞吗?不过,interrupt()是解除
wait()或者sleep()阻塞,如果是其他原因引起阻塞,那么就调用相应的办法,比如socket用close(),或者,你可以override interrupt()方法,在interrupt同时解除你特有的阻塞。

[ 本帖最后由 perryhg 于 2006-6-21 18:39 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2006-06-23 15:03 |只看该作者
我现在做的项目就有这样的问题,我们是这样解决的:

1、把阻塞改成不阻塞,比如MQ,就可以不阻塞通讯;

2、使阻塞的源头异常,比如关闭Socket。

BTW:楼上的好几个高手都提到了杀死线程,你在Java里杀死过线程吗?怎么弄?我一直都没学会!我的经验是:除了线程自己出Run方法或整个Application结束或虚拟机崩溃以外,是不能主动杀死一个线程的!

[ 本帖最后由 我是好人 于 2006-6-23 15:04 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2006-06-23 15:52 |只看该作者
  1. interrupt()是不可能保证终止线程的,stop()又是Deprecated的,我的做法是:
  2. if (thread != null && thread.isAlive()) {
  3.                 thread.interrupt();
  4.                 try {
  5.                     thread.join(3000);
  6.                 } catch (InterruptedException e) {
  7.                     //log
  8.                 }
  9.                 if (thread.isAlive()) {
  10.                     //log
  11.                     thread.stop();
  12.                 } else {
  13.                     //log
  14.                 }
  15.                 thread = null;
  16.             }
复制代码

论坛徽章:
0
10 [报告]
发表于 2006-06-23 22:07 |只看该作者
原帖由 aixy 于 2006-6-23 15:52 发表
[code]interrupt()是不可能保证终止线程的,stop()又是Deprecated的,我的做法是:
if (thread != null && thread.isAlive()) {
                thread.interrupt();
                try {
        ...

不明白你把 thread.interrupt(); 放在第一行有什么用,另外, thread.stop();应该禁止使用!

interrupt()不是为了终止线程,而是解除wait()或sleep()造成的阻塞,当你有使用wait或者sleep的时候,可以这样用

try{
    wait();
     ...
catch(InterruptedException e)
{
    stopThread();
}

private void stopThread()
{
//清理线程资源
...
}

当你需要去终止一个用wait()或者sleep()阻塞中的线程,interrupt可以帮助你。而其他的阻塞比如socket就跟interrupt无关了。

线程的终止的代码还是得自己来实现,毕竟每个线程所实现的功能和使用的资源都不同,有些资源如果不进行显示释放,可能只有等jvm退出运行才会释放了,如果你运行的是个服务器程序,那么很快就会吃光内存而导致出错退出了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP