论坛首页 入门技术论坛

不可能完成任务?Thread的超时自动终止

浏览 29293 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-29  
kowen 写道
ispring 写道
看看 Http-Client 中怎么处理的吧,对于兼容1.4中建立Socket超时问题的解决方案:

/**
     * Executes <code>task</code>. Waits for <code>timeout</code>
     * milliseconds for the task to end and returns. If the task does not return
     * in time, the thread is interrupted and an Exception is thrown.
     * The caller should override the Thread.interrupt() method to something that
     * quickly makes the thread die or use Thread.isInterrupted().
     * @param task The thread to execute
     * @param timeout The timeout in milliseconds. 0 means to wait forever.
     * @throws TimeoutException if the timeout passes and the thread does not return.
     */
    public static void execute(Thread task, long timeout) throws TimeoutException {
        task.start();
        try {
            task.join(timeout);
        } catch (InterruptedException e) {
            /* if somebody interrupts us he knows what he is doing */
        }
        if (task.isAlive()) {
            task.interrupt();
            throw new TimeoutException();
        }
    }


我写了一个ThreadA,用以上方法运行结果还是不行
public class ThreadA extends Thread {
	
	private long startTime;

	public ThreadA(String name) {
		super(name);
	}

	public void run() {
		this.startTime = System.currentTimeMillis();
		int i = 0;
		while (i++<20) {
			try {
				this.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(this.getName()+":"+i);
		}

		System.out.println(this.getName()+"已完成");

	}
}


结果:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at thread.ThreadA.run(ThreadA.java:22)
Exception in thread "main" java.util.concurrent.TimeoutException
at thread.Test.execute(Test.java:28)
a:1
at thread.Test.main(Test.java:16)
a:2
a:3
a:4
a:5
a:6
a:7
a:8
a:9
a:10
a:11
a:12
a:13
a:14
a:15
a:16
a:17
a:18
a:19
a:20
a已完成

说明Thread还是运行完成了,没有被终止,这种方式只能通知客户端超时,服务端还是继续运行



把你的 main 方法帖出来吧
0 请登录后投票
   发表时间:2009-04-29  
public class ThreadTest extends TestCase {

	public void testJoin() {
		Task task = new Task();
		task.start();
		try {
			task.join(5 * 1000);	// 5 seconds to reach timeout
		} catch (InterruptedException e) {
			System.out.println("Interrupted in main");
		}
		System.out.println("OK, It's over");
	}
}

class Task extends Thread {

	@Override
	public void run() {
		int count = 0;
		while(true) {
			try {
				this.sleep(1000);
			} catch (InterruptedException e) {
				System.out.println("Interrupted in thread");
			}
			System.out.println("I am running..." + ++count);
		}
	}
}
1 请登录后投票
   发表时间:2009-04-29  
还没太明白。
不过,jdk1.5之后,线程的启动和停止不是提倡用ExecutorService 的execute(Runnable) 和shutdown()了么?
0 请登录后投票
   发表时间:2009-04-29   最后修改:2009-04-29
设计影子线程可以解决:A线程+A影子线程,同时启动,后者负责A线程的生存周期,并在结束A线程的同时结束自己。

这个任务很久之前设计过,是一个高负载的业务Log,为了应付瞬时可能过100的并发log请求,实践证明是完全可以完成的。

楼主先考虑一下我这个思路,不行我再去找以前的源代码。
0 请登录后投票
   发表时间:2009-04-29   最后修改:2009-04-29
public class ThreadA extends Thread {

     private long startTime;

     public ThreadA(String name) {
      super(name);
     }

    public void run() {
   this.startTime = System.currentTimeMillis();
   int i = 0;
   while (i++<20) {
   try {
       this.sleep(100);
   } catch (InterruptedException e) {
        e.printStackTrace();
      return;

   }
   System.out.println(this.getName()+":"+i);
 }

   System.out.println(this.getName()+"已完成");

 }
}

 

0 请登录后投票
   发表时间:2009-04-29  
还是没解决了啊 我等了一天想看看呢~!
0 请登录后投票
   发表时间:2009-04-29  
想什么呢? 难道各位没有研究过基础的OS THREAD问题?  要完美的实现THREAD终止是无解的。  最好的办法是你要在代码的每个步骤确定是否要终止执行, 通知的方式可以通过JAVA5提供的 Timer API完成。 

具体为什么无解,还是去看程序执行的机制吧。 JAVA放弃了stop的API正是这个原因--可能导致严重的系统资源泄露。
1 请登录后投票
   发表时间:2009-04-29   最后修改:2009-04-29
..放弃了stop不是由于synchronized这个东西造成的吗...

难道还有更大的 隐患吗
0 请登录后投票
   发表时间:2009-04-29   最后修改:2009-04-29
放弃stop()是因为它不释放线程获得的锁。还有其它的原因。
多线程很让人晕乎。OS Thread机制更是没了解过。
完美不完美得看楼主的具体的应用。完美也是相对的。

在Thinking In Java第四版21章里有关于终止线程的介绍。
0 请登录后投票
   发表时间:2009-04-29  
除非你调用Thread的stop方法,否则你不可能精确地做到超时的线程退出,因为线程在执行一个方法的时候,这个方法可能很耗时,所以用设置标量的方法是不可行的,设置标量的方法可以用在线程是循环执行小的不耗时的方法的时候。
而每次执行前检查一下是否要退出线程也是不可靠的,就是因为上述的原因,一个方法可能会执行很长时间。

此题要想解决,只能把大的耗时的任务分解为小的循环式的来执行的,这样可以用一个boolean值来控制循环是否退出从而结束某个线程。

stop方法之所以过时,是因为1,它相当于进程里面的杀死进程,用这种方法来强行杀死线程会使得很多关键的数据或者操作得不到完整性的保证。2,它不会释放对象锁。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics