<< 换一种态度看程序员 | 首页 | 软件架构概念大观 >>

java 线程超时中断实现

有一个需求,就是当一个方法执行超时的时候就中断该方法. 
java的超时实现,在网上搜到的大部分是: 
方法1. 
  中断线程最好的,最受推荐的方式是,使用共享变量(shared variable)发出信号,告诉线程必须停止正在运行的任务。线程必须周期性的核查这一变量(尤其在冗余操作期间),然后有秩序地中止任务。Listing B描述了这一方式。

Listing B
class Example2 extends Thread {

  volatile boolean stop = false;

  public static void main( String args[] ) throws Exception {

    Example2 thread = new Example2();

   System.out.println( "Starting thread..." );

   thread.start();

   Thread.sleep( 3000 );

   System.out.println( "Asking thread to stop..." );

   thread.stop = true;

   Thread.sleep( 3000 );

   System.out.println( "Stopping application..." );

   //System.exit( 0 );

  }

  public void run() {

    while ( !stop ) {

     System.out.println( "Thread is running..." );

      long time = System.currentTimeMillis();

      while ( (System.currentTimeMillis()-time < 1000) && (!stop) ) {

      }

    }

   System.out.println( "Thread exiting under request..." );

  }

}
另外,httpclient中就提供了这样一个class- timeoutcontroller(位于org.Apache.commons.httpclient.util包内)查看该class的源代码可知其实现细节:
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();
        }
    }
其实就是通过join()和interrupt()方法实现这种功能,文档中强调了task的interrupt()方法必须重写(override)

方法2. 
   用join,就是在主线程里开一个子线程(t),在子线程里去处理超时任务,主线程t.join(3000),3000为要等待的时间(ms),如果子线程没有超时则正常继续执行,如果超时了则中断该子线程t.interrupt(); 
   代码如下: 
  

Java代码 
  1. public class ThreadTest {  
  2.   
  3.     public static void main(String[] args) {  
  4.      
  5.         CounterThread ct = new CounterThread(5000);  
  6.        
  7.         System.out.println("start...");  
  8.           
  9.         System.out.println("ct start...");  
  10.         ct.start();  
  11.    
  12.         System.out.println("ct join...");  
  13.         try {  
  14.             ct.join(2000);  
  15.         } catch (InterruptedException e) {  
  16.             e.printStackTrace();  
  17.         }  
  18.         System.out.println(ct.isAlive());  
  19.         ct.interrupt();  
  20.         System.out.println(ct.isAlive());  
  21.           
  22.         System.out.println("the result is " + ct.getResult());  
  23.   
  24.     }  
  25.   
  26. }  
  27.   
  28. class CounterThread extends Thread {  
  29.     private int time;  
  30.     public CounterThread(int time) {  
  31.         this.time = time;  
  32.     }  
  33.   
  34.     private int result;  
  35.   
  36.     public int getResult() {  
  37.         return result;  
  38.     }  
  39.   
  40.     public void run() {  
  41.         try {  
  42.              
  43.             Thread.sleep(time);  
  44.             System.out.println(Thread.currentThread().getName()  
  45.                     + " is blocked for " + time + "ms");  
  46.         } catch (InterruptedException ex) {  
  47.   
  48.         }  
  49.         result = 5;  
  50.     }  
  51. }  



这种方式是可以的,其实还有另外一种方式,就是 

Java代码 
  1. public class TimeoutTest1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         final ExecutorService service = Executors.newFixedThreadPool(1);  
  5.   
  6.         TaskThread taskThread = new TaskThread();  
  7.   
  8.         System.out.println("提交任务...begin");  
  9.          
  10.         Future<Object> taskFuture = service.submit(taskThread);  
  11.         System.out.println("提交任务...end");  
  12.         try {  
  13.             System.out.println("get .... begin");  
  14.             Object re = taskFuture.get(1000, TimeUnit.MILLISECONDS);  
  15.             System.out.println(re);  
  16.             System.out.println("get .... end");  
  17.         } catch (InterruptedException e) {  
  18.             e.printStackTrace();  
  19.         } catch (ExecutionException e) {  
  20.             e.printStackTrace();  
  21.         } catch (TimeoutException e) {  
  22.             System.out.println("超时 取消任务");  
  23.             taskFuture.cancel(true);  
  24.             System.out.println("超时 取消任务OK");  
  25.         }finally{  
  26.             System.out.println("关闭服务");  
  27.             service.shutdown();  
  28.             System.out.println("关闭服务OK");  
  29.         }  
  30.   
  31.     }  
  32.   
  33. }  
  34. class TaskThread implements Callable<Object> {  
  35.          
  36.   
  37.     public Object call() throws Exception {  
  38.         String result = "空结果";  
  39.         try {  
  40.             System.out.println("任务开始....");  
  41.             Thread.sleep(5000);  
  42.             result = "正确结果";  
  43.             System.out.println("任务结束....");  
  44.         } catch (Exception e) {      
  45.             System.out.println("Task is interrupted!");  
  46.         }  
  47.         return result ;  
  48.     }  
  49.   
  50. }  

 

标签 : ,



发表评论 发送引用通报