如何从监视器中断另一个线程线程
我知道这是不适当的建议,但我仍然试图寻找一种方法来中断挂起的线程,从另一个线程是保持时间。如何从监视器中断另一个线程线程
我所做的是: 我在即将发生可疑的网络操作之前启动监视器线程。该线程应该监视自启动以来的时间,如果时间超过某个阈值,它会杀死最初启动它的线程。为了通知这个新线程,要杀死哪个线程,新线程的对象被传递给要被监视的线程对象。
简单地说,这是发生了什么:
A创建B,B创建C,B告诉C约本身,C保持时间,如果时间过期Ç杀死B(我传递的细节到C后B的运行方法使用“currentThread()”,并且我已经确认正确的对象确实正在通过)
现在,问题在于,由于某种原因,此操作不起作用,因此调用B.interrupt )正在杀死C本身。
[注意:大写字母表示螺纹名称]
如果您问我,这实际上是正常行为。如果你打断B,它将被垃圾收集。由于对C的唯一引用也是GC'd,它将停止存在/运行。
最好的想法可能是确保有一个线程管理线程B和C(并将线程C插入线程B)。这样,总是有一个线程C的引用,它可以杀死线程B.(但是你必须小心你在管理线程中使用线程B做什么)
其实,那是我相信,但是,我观察到的是,C被破坏,B继续存在。 – angryInsomniac 2010-08-05 07:04:58
我认为线程有来自ThreadGroup对象的引用。在这个例子中,我不会线程C是CG'd – 2010-08-05 07:06:29
是的,线程不是那样的GCd。 – 2010-08-05 08:15:29
检查在调用时是否得到SecurityException
B.interrupt()
。另外,您确定您的B.interrupt()
不会简单地返回并且线程C成功完成吗?基于javadocs,它看起来像线程C的B.interrupt()
调用将设置线程B的中断状态并完成运行。我不认为线程B会在你的情况下得到任何异常,除非它满足特殊要求(例如,等待监视器,等待InterruptibleChannel
等)。
据我所见,代码中任何地方都不会抛出任何异常 – angryInsomniac 2010-08-05 08:24:30
您可以发布您的监控线程的代码吗? – 2010-08-05 08:38:51
我认为你的代码有问题(除非我没有明确你的规格)。下面的代码运行正常(对不起,可怕的嵌套结构):
产量为:
C is about to interrupt B
B is interrupted
C is still alive... is B alive yet?false
代码为:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
public class Scrap {
public static void main(String[] args) {
Thread A = new Thread() {
@Override
public void run() {
Thread B = new Thread() {
@Override
public void run() {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<Thread> pointer = new AtomicReference<Thread>();
Thread C = new Thread() {
@Override
public void run() {
try {
//wait for B to be ready
latch.await();
Thread.sleep(2000);
System.out.println("C is about to interrupt B");
pointer.get().interrupt();
Thread.sleep(2000);
System.out.println("C is still alive... is B alive yet? " + pointer.get().isAlive());
} catch (InterruptedException e) {
System.out.println("C interrupted");
return;
}
}
};//C
C.start();
latch.countDown();
//Not sure how you did it, so just going with this:
pointer.set(Thread.currentThread());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("B is interrupted");
return;
}
System.out.println("B survived");
}
};//B
B.start();
}
};
A.start();
}
}
我的(野生)的猜测是线程间的能见度。在上面的代码中,我使用原子引用来确保可见性。如果你没有这样做,可能无论你传递线程B的引用(的值)的任何字段可能对C而言都是不可见的。然后,当C尝试中断这个线程对象时,它看到null,并且中断导致NullPointerExceptin ,不知何故,你没有注意到它?
另一种可能性是,C中断成功并返回,但B不响应。这是很有可能的,因为如果B被相应地编码,中断只会起作用。
有2种方式来应对中断。
1。检查中断标志
if(Thread.currentThread().isInterrupted()){
log.info("Cancel requested");
return;
}
someStuffThatTakesLongTimeToExecute();
2.Act对中断例外
catch(InterruptedException e){
log.info("Cancel Requested");
//Preserve interrupted status.
//If this class is the owner of the thread,
//Not necessary.
Thread.currentThread().interrupt();
return;
}
什么是C到死的原因(通常是需要很长时间的操作之前)?任何堆栈跟踪?你知道它肯定会死吗?你能发布你的监控线程的代码吗? – 2010-08-05 07:02:35
http://pastebin.com/JVfpkqEg这里是监视器代码的链接,“Hourglass”只是我制作的一个小型定时器类,在构造函数中你可以在几秒钟内超时,然后你就可以开始,停止或检查任务是否完成。 – angryInsomniac 2010-08-05 09:02:42
评论继续:我没有看到C死亡的任何理由,没有错误报告,所以我不能给你任何堆栈跟踪。 我确信它死了,因为我在eclipse中实时观察线程执行,只要执行必要的语句,线程C就会死掉。 – angryInsomniac 2010-08-05 09:14:33