zoukankan      html  css  js  c++  java
  • JAVA处理线程超时

    在实际业务中,由其是多线程并开业务中,经常会遇到某个线程执行超时。而程序如果不捕获这类情况,就会导致程序一直处于等待状态,从而影响后续线程的运行。
    比如说网络通迅、单任务下的复杂数据库查询等,通常处理这类问题,可以启用一个后台守护线程来监控用户线程(业务线程)的执行是否超时,如果超时就不在等待,这种做法,通常是在调用用户线程的.start()方法之前,调用守护线程的start()方法,同时将超时时长传给守护线程。在守护线程的run()方法,执行sleep()方法,休眠时间为超时时长,守护线程中有一个同步后的变量用于存储用户线程是否超时。而在用户线程中,在程序执行完之后,再调用守掮线程改变同步变量。当守护线程sleep()方法之后,去有判断同步变量的值是否已改变,如果没有改变,说明用户线程还未扫行完毕,也就是超时。但这种方法,不能中断用户线程。
    除此之外,还有一种方法,可以中断用户线程不在继续运行,采用java.util.concurrent下面的接口、类也可以完成。以下是例子。

    Java代码  收藏代码
    1. import java.util.concurrent.Callable;  
    2. import java.util.concurrent.ExecutionException;  
    3. import java.util.concurrent.ExecutorService;  
    4. import java.util.concurrent.Executors;  
    5. import java.util.concurrent.Future;  
    6. import java.util.concurrent.TimeUnit;  
    7. import java.util.concurrent.TimeoutException;  
    8.   
    9. public class TimeOut {  
    10.     public static void main(String[] args){  
    11.         int timeout = 2//秒.  
    12.         ExecutorService executor = Executors.newSingleThreadExecutor();  
    13.         Boolean result = false;     
    14.         Future<Boolean> future = executor.submit(new MyJob("请求参数"));// 将任务提交到线程池中     
    15.         try {     
    16.             result = future.get(timeout*1000, TimeUnit.MILLISECONDS);// 设定在200毫秒的时间内完成   
    17.             System.out.println(result);  
    18.         } catch (InterruptedException e) {  
    19.             System.out.println("线程中断出错。");  
    20.             future.cancel(true);// 中断执行此任务的线程     
    21.         } catch (ExecutionException e) {     
    22.             System.out.println("线程服务出错。");  
    23.             future.cancel(true);// 中断执行此任务的线程     
    24.         } catch (TimeoutException e) {// 超时异常     
    25.             System.out.println("超时。");     
    26.             future.cancel(true);// 中断执行此任务的线程     
    27.         }finally{  
    28.             System.out.println("线程服务关闭。");  
    29.             executor.shutdown();  
    30.         }  
    31.     }  
    32.       
    33.     static class MyJob implements Callable<Boolean> {    
    34.         private String t;  
    35.         public MyJob(String temp){  
    36.             this.t= temp;  
    37.         }  
    38.         public Boolean call() {     
    39.             for(int i=0;i<999999999;i++){  
    40.                 if(i==999999997){  
    41.                     System.out.println(t);  
    42.                 }  
    43.                 if (Thread.interrupted()){ //很重要  
    44.                     return false;     
    45.                 }  
    46.             }   
    47.             System.out.println("继续执行..........");     
    48.             return true;     
    49.         }     
    50.     }   


    在做socket通信时我这边服务端需要设置超时程序(客户端为硬件终端连接,没有回应几分钟内设置超时程序)

    此socket服务端启动使用timertask类型,启动后再开几十个线程来处理终端连接。。。

    我试了两种超时程序都蛮好:一种是通过线程的join设置,一种是通过concurrent的Future手段

    join:

    public class ThreadTest { 
        public static void main(String[] args) {   
            CounterThread ct = new CounterThread();   
            ct.start();
            try {   
                ct.join(20000);  //超时的时间,如20秒
                if(ct.isAlive()){//说明再设定的时间内没有执行完,超时
                      ct.interrupt(); 
                      throw new TimeoutException();//抛出,让socket线程终止
                }
                ct.getResult();//正常情况下可以获取执行后的值
            } catch (InterruptedException e) {   
                e.printStackTrace();   
            } 
        } 

    class CounterThread extends Thread {   
        public CounterThread(int time) {  
             构造函数,传递一些有用的值给run;
        }  
        private int result;   
      
        public int getResult() {//在上面获取的结果值
            return result;   
        } 
        public void run() {   
                   result = 执行的任务,如读取客户端数据; 
        }   

    Furture:

    public class TimeoutTest1 {

     public static void main(String[] args) {
      final ExecutorService service = Executors.newFixedThreadPool(1);

      TaskThread taskThread = new TaskThread();
      System.out.println("提交任务...begin");
      Future<Object> taskFuture = service.submit(taskThread);
      System.out.println("提交任务...end");
      try {
       Object re = taskFuture.get(6000, TimeUnit.MILLISECONDS);//超时设置,6s
       System.out.println(re);
      } catch (InterruptedException e) {
       e.printStackTrace();
      } catch (ExecutionException e) {
       e.printStackTrace();
      } catch (TimeoutException e) {
       System.out.println("超时 取消任务");
       taskFuture.cancel(true);
       System.out.println("超时 取消任务OK");
      } finally {
       service.shutdown();
      }

     }

    }

    class TaskThread implements Callable<Object> {

     public Object call() throws Exception {
      String result = "空结果";
      try {
       System.out.println("任务开始....");
       Thread.sleep(5000);
       result = "正确结果";
       System.out.println("任务结束....");
      } catch (Exception e) {
       System.out.println("Task is interrupted!");
      }
      return result;
     }

    }


  • 相关阅读:
    Changing Icon File Of Push Button At Runtime In Oracle Forms 6i
    Set Font Properties On Mouse Hover Of Push Button And Text Items At Run time In Oracle Forms
    Change An Item Property Using Set_Item_Property In Oracle Forms
    Calling / Running a report in Oracle forms 10g / 11g
    Change Or Set Report Object Property At Run Time In Oracle Forms Using Set_Report_Object_Property Command
    Refresh / Updating a form screen in Oracle D2k Forms 6i
    Know How And When To Use System.Message_Level To Control Messages In Oracle Forms
    Perform Cut Copy Paste Operations Using Cut_Region Copy_Region Paste_Region Commands In Oracle Forms
    CHECKBOX_CHECKED built-in in Oracle D2k Forms
    Limiting To Select Only 5 Check Boxes Out Of Ten In Oracle Forms
  • 原文地址:https://www.cnblogs.com/kuyuyingzi/p/4266328.html
Copyright © 2011-2022 走看看