浏览 919 次
|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2008-09-13
大家都知道线程是不可靠的,我想了一些办法去监视线程当前的运行状态,能得到比如该线程到了那个类的那个方法了,到了哪一行了,在细粒度的控制上还是有一定作用的。
之前去实现jdk里的Observer接口写了一个,但是发现 实际上还是由线程自己触发内部的event后,listener才能响应,一旦线程阻塞,没有event了,listener也没有意义了。这样始终是被动得到线程发出的信息。 想要主动的获得线程的运行信息,需要一个timer 定时去主动获取它的状态,也就是获得当前线程对象的方法堆栈。 如果发现目标线程已经结束,则关闭监视器。如果因为发生预期外的阻塞而timeout,也关闭监视器,由于已经将目标线程设置成deamon,目标线程也将结束。 这样能完全掌握目标线程的一举一动,不听话就干掉。是不是很有快感? ThreadMonitor使用办法 ThreadMonitor thread = new ThreadMonitor(new OneThread(),5000,1000); thread.start(); ThreadMonitor: public class ThreadMonitor {
private Thread thread;
private Timer timer = new Timer();
private long period,timeout,startTime;
private boolean isFirst;
public ThreadMonitor(Thread thread,long timeout,long period){
this.thread = thread;
init(timeout, period);
}
public ThreadMonitor(Runnable runnable,long timeout,long period){
thread = new Thread(runnable);
init(timeout, period);
}
private void init(long timeout,long period){
isFirst = true;
this.period = period;
this.timeout = timeout;
startTime = System.currentTimeMillis();
}
public void start(){
timer.schedule(new TimerTask(){
public void run() {
if(isFirst)
thread.setDaemon(true);
boolean isTimeout = System.currentTimeMillis() - startTime>timeout;
if(!isFirst && (isTimeout || !thread.isAlive())){
timer.cancel();
if(!isTimeout && !thread.isAlive())
System.out.println("Thread is over");
if(isTimeout)
System.out.println("Timeout");
if(!thread.isAlive())
System.out.println("Close target thread");
System.out.println("Close thread monitor");
}else {
long now = System.currentTimeMillis();
StackTraceElement elements[] = thread.getStackTrace();
if(elements.length >0)
for(StackTraceElement element : elements){
System.out.println("["+(now-startTime)+"] Current: "+ element.getClassName()+" " +element.getMethodName()+"() line:"+element.getLineNumber());
}
else
System.out.println("Stack is null");
}
isFirst = false;
}
}, 0, period);
thread.start();
}
}
下面是例子 OneThread: public class OneThread implements Runnable {
public void run() {
ThreadUtil util = new ThreadUtil();
util.step1();
util.step2();
util.step3();
}
}
ThreadUtil: public class ThreadUtil {
public void step1(){
synchronized(this){
try {
wait(1000);
} catch (InterruptedException e) {
System.out.println("1:"+e.getMessage());
}
}
System.out.println("step1 finished");
}
public void step2(){
synchronized(this){
try {
wait(3000);
} catch (InterruptedException e) {
System.out.println("3:"+e.getMessage());
}
}
System.out.println("step3 finished");
}
public void step3(){
synchronized(this){
try {
wait(2000);
} catch (InterruptedException e) {
System.out.println("3:"+e.getMessage());
}
}
System.out.println("step3 finished");
}
}
下面是输出: Stack is null [1002] Current: java.lang.Object wait() line:-2 [1002] Current: org.jomper.test.thread.ThreadUtil step1() line:7 [1002] Current: org.jomper.test.thread.OneThread run() line:7 [1002] Current: java.lang.Thread run() line:595 step1 finished [2006] Current: java.lang.Object wait() line:-2 [2006] Current: org.jomper.test.thread.ThreadUtil step2() line:17 [2006] Current: org.jomper.test.thread.OneThread run() line:8 [2006] Current: java.lang.Thread run() line:595 [3010] Current: java.lang.Object wait() line:-2 [3010] Current: org.jomper.test.thread.ThreadUtil step2() line:17 [3010] Current: org.jomper.test.thread.OneThread run() line:8 [3010] Current: java.lang.Thread run() line:595 step2 finished [4010] Current: java.lang.Object wait() line:-2 [4010] Current: org.jomper.test.thread.ThreadUtil step3() line:27 [4010] Current: org.jomper.test.thread.OneThread run() line:9 [4010] Current: java.lang.Thread run() line:595 Timeout Close thread monitor 大家来讨论把,还有没有更好的办法,或者思路上有没有问题,有没有想错的地方。 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2008-02-20
我犯了一个错误,之前把thread.setDaemon(true); 方到TimeTask之外了.成了主线程不消亡target thread就不消亡,我并没有干掉target thread!
现在我把他放到TimeTask里,从输出里可以看到,target thread的确是已经终止了。System.out.println("step3 finished"); 并没有输出。 现在有一种办法是在 target thread 内部设置 标志位,然后double check.来终止线程内部流程而使 target thread 终止。 public void run(){
while(!isInterrupted){
//todo process
}
}这样安全,但是这样就有入侵.
把target thread 设置成守护线程,通过主线程的可控性终止来间接实现 target thread的终止,这是不是也是一种思路呢? |
|
| 返回顶楼 | |


