不用STOP()方法怎么强制并且较安全的退出僵死的JAVA线程?请大虾们帮帮忙!

ckaqlr2100 2009-11-16 12:16:31
Interrupt 方法必须要捕获了InterruptedException才能起作用,在处理IO流时 还被忽略。。。
不用STOP()方法怎么强制并且较安全的退出僵死的JAVA线程?请大虾们帮帮忙!
...全文
652 18 打赏 收藏 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
icekay Song 2009-11-16
  • 打赏
  • 举报
回复
所谓的监控是指主线程监控? 还是主线程另启一个线程监控? = =
icekay Song 2009-11-16
  • 打赏
  • 举报
回复
学习一下,你们继续! 呵呵 , 很受教啊...
很想知道系统进程死后,是如何解决的,应该也只是强制kill掉吧...
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
同时通过在一个Java虚拟机内,可以完成线程的监控 当发现莫个线程僵死或超时,主线程可以去kill掉它
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
恩,是的,我这样做是模拟程序在执行某段代码时僵死的情况,当然这样模拟很欠缺妥当。但是说明了使用interrupt()方法去结束线程的问题。
为此我痛苦了两天。我就想通过某个方案设计或好的方法,可以在需要和恰当的时候保证完成线程的结束任务。
bayougeng 2009-11-16
  • 打赏
  • 举报
回复
是的,这是结束线程的两种常规方法。我明白你的意思。
你想用标志位,那你的内层while循环就必须判断标志位。而不是while(true)。
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
那个isDeath标志位不是问题的关键
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
isDeath作为信号的那个循环最后有break;
你把
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程
while (true) {
Thread.sleep(10);
if (count == 2)
{
break;
}

}
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程

中的 Thread.sleep(10); 这行代码去掉再运行Test2 线程就停不了了。
原因是内部不具备抛出 InterruptedException 的条件。测试类调用interrupt() 方法就不起作用。
bayougeng 2009-11-16
  • 打赏
  • 举报
回复
!!
如果你想用isDeath做为标志位的话,那内层循环的条件就应该是while(isDeath)。
如果你想用捕获异常的方式结束线程,那就得用sleep。
bayougeng 2009-11-16
  • 打赏
  • 举报
回复
我看错了,如果你的ThreadTest_2#terminate是这样:
public void terminate(){
isDeath = false;
}

那按照你原来的代码不能结束线程,因为你的循环没用isDeath作为信号。
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
public void terminate()
{
isDeath = true;
interrupt();
}
以上是ThreadTest_2#terminate的代码,你能结束的原因是:
ThreadTest_2类中的Thread.sleep(10);没有注释掉,如果没有这行代码就停不了了。
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程
while (true) {
Thread.sleep(10); if (count == 2) {
break;
}

}
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程

ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
我 看下代码
bayougeng 2009-11-16
  • 打赏
  • 举报
回复
我按照你给的部分代码,复原了两个类。你看看下面的代码。
public class ThreadTest_2 extends Thread {

private boolean isDeath;

private int count;

private boolean finish;

public void run() {

try {
// 任务开始时先停一指定时间
// 目的是让外部的join()方法有时间执行
Thread.sleep(1000);

while (!isDeath) {
// Thread.sleep(1000);
// some statements .... 运行相关任务
System.out.println("start working ... " + this.getName());

// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程
while (true) {
Thread.sleep(10);
if (count == 2) {
break;
}

}
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程

// 任务周期计数
count++;

// 任务完成
finish = true;

Thread.sleep(1000);

// 这里为了测试设置任务只执行一次
break;
}
} catch (InterruptedException e) {
System.out.println("I'm interrupted ! OK The Thread "
+ this.getName() + " is over !");
}
}

public boolean isFinish(){
return finish;
}

public void terminate(){
isDeath = false;
}
}

public class Test_2 {
public static void main(String[] args) {
System.out.println("初始化... ");

System.out.println("开始测试 ...");

// 开始任务
ThreadTest_2 s1 = new ThreadTest_2();
ThreadTest_2 s2 = new ThreadTest_2();

s1.start();
s2.start();

try {
s1.join(2000);
s2.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}

try {
if (!s1.isFinish()) {
System.out.println("s1 is alive : " + s1.isAlive());
s1.interrupt();
Thread.sleep(500);
System.out.println("s1 is alive : " + s1.isAlive());

System.out.println("s1 Thread " + s1.getName() + " ? ");
// s1.stop();
System.out.println("s1 is over!");
}

if (!s2.isFinish()) {
System.out.println("s2 is alive : " + s2.isAlive());
s2.interrupt();
Thread.sleep(500);
System.out.println("s2 is alive : " + s2.isAlive());

System.out.println("s2 Thread " + s2.getName() + " ? ");
// s2.stop();
System.out.println("s2 is over!");
}
} catch (InterruptedException e) {
e.printStackTrace();
}



// System.exit(0) ;
}

}

你运行一下Test_2就明白了。
是你的pg跑的太快了,没有来得及看见线程结束的信息。
如果我猜的代码不是你想要的意思,你把完整的代码发上来。
另外,ThreadTest_2#terminate我不知道你怎么定义的,可能是这样:
public void terminate(){
isDeath = false;
}
如果是这样的话,按照你原来的代码,也是能结束线程的,只不过你需要用sleep才能看见。
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
调用时 如果线程类里
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程
while (true) {
Thread.sleep(10);
if (count == 2) {
break;
}

}
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程

死循环一直被调用,且没有Thread.sleep(10);这行代码,Interrupt()方法无法捕获异常就无法停止线程
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
外层的调用:
public class Test_2
{
public static void main(String[] args)
{
System.out.println("初始化... ");

System.out.println("开始测试 ...");

//开始任务
ThreadTest_2 s1 = new ThreadTest_2();
ThreadTest_2 s2 = new ThreadTest_2();

s1.start();
s2.start();

try
{
s1.join(2000);
s2.join(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}

try
{
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

if(!s1.isFinish())
{
System.out.println("s1 is alive : " + s1.isAlive());
s1.terminate();
System.out.println("s1 is alive : " + s1.isAlive());

System.out.println("s1 Thread " + s1.getName() + " ? " );
// s1.stop();
System.out.println("s1 is over!");
}

if(!s2.isFinish())
{
System.out.println("s2 is alive : " + s2.isAlive());
s2.terminate();
System.out.println("s2 is alive : " + s2.isAlive());

System.out.println("s2 Thread " + s2.getName() + " ? " );
// s2.stop();
System.out.println("s2 is over!");
}

}

}
不好意思 想吧完整的框架发一下的,式了多此没发出来,您看下这时外层大体的调用
bayougeng 2009-11-16
  • 打赏
  • 举报
回复
	public void run() {
try {
// 任务开始时先停一指定时间
// 目的是让外部的join()方法有时间执行
Thread.sleep(1000);

while (!isDeath) {
// Thread.sleep(1000);
// some statements .... 运行相关任务
System.out.println("start working ... " + this.getName());

// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程
while (true) {
Thread.sleep(10);
if (count == 2) {
break;
}

}
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程

// 任务周期计数
count++;

// 任务完成
finish = true;

Thread.sleep(1000);

// 这里为了测试设置任务只执行一次
break;
}
} catch (InterruptedException e) {
System.out.println("I'm interrupted ! OK The Thread "
+ this.getName() + " is over !");
}


是这样的吧?你在哪调用interrupt让它停止呢?
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
public void run ()
{
try
{
// 任务开始时先停一指定时间
// 目的是让外部的join()方法有时间执行
Thread.sleep(1000);

while(!isDeath)
{
// Thread.sleep(1000);
// some statements .... 运行相关任务
System.out.println("start working ... " + this.getName());

// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程
while(true)
{
Thread.sleep(10);
if(count == 2)
{
break;
}

}
// 模拟僵死A 没有机会抛InterruptedException 根本无法中断线程


//任务周期计数
count ++;



// 任务完成
finish = true;

Thread.sleep(1000);

// 这里为了测试设置任务只执行一次
break;
}
}
catch (InterruptedException e)
{
System.out.println("I'm interrupted ! OK The Thread "
+ this.getName() + " is over !");
}

如我上一个帖子所说 当while(true)是一个死循环时 外部线程根本无法通过interrupt()方法来中断此线程。除了用stop()方法,但是 stop()方法已经过时,且会造成对象数据的崩溃。哎伤脑筋,对SUN的API有点失望。
ckaqlr2100 2009-11-16
  • 打赏
  • 举报
回复
感谢您关注我的问题,Java中停止线程的方法stop() 已经过期,
我们想寻找一种能够比较安全的退出线程的方法,
interrupt() 方法太被动了
在不能捕获 interruptedException时无法中断线程。
太头痛了!
不知大侠在处理此类问题上有何好的方法。在此真心表示感谢!
bayougeng 2009-11-16
  • 打赏
  • 举报
回复
既然是僵死的线程,它怎么会响应你发出的退出请求呢?
如果连请求都不能响应的话,退出又何来安全一说?
合理的处理方式是,别让你的pg出现僵死的线程。那是bug。

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧