【轉】JAVA處理執行緒超時

java_lover發表於2017-04-11

在實際業務中,由其是多執行緒並開業務中,經常會遇到某個執行緒執行超時。而程式如果不捕獲這類情況,就會導致程式一直處於等待狀態,從而影響後續執行緒的執行。
比如說網路通迅、單任務下的複雜資料庫查詢等,通常處理這類問題,可以啟用一個後臺守護執行緒來監控使用者執行緒(業務執行緒)的執行是否超時,如果超時就不在等待,這種做法,通常是在呼叫使用者執行緒的.start()方法之前,呼叫守護執行緒的start()方法,同時將超時時長傳給守護執行緒。在守護執行緒的run()方法,執行sleep()方法,休眠時間為超時時長,守護執行緒中有一個同步後的變數用於儲存使用者執行緒是否超時。而在使用者執行緒中,在程式執行完之後,再呼叫守掮執行緒改變同步變數。當守護執行緒sleep()方法之後,去有判斷同步變數的值是否已改變,如果沒有改變,說明使用者執行緒還未掃行完畢,也就是超時。但這種方法,不能中斷使用者執行緒。
除此之外,還有一種方法,可以中斷使用者執行緒不在繼續執行,採用Java.util.concurrent下面的介面、類也可以完成。以下是例子。

package com.test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;  
  
public class TimeOut {  
    public static void main(String[] args){  
        int timeout = 2; //秒.  
        ExecutorService executor = Executors.newSingleThreadExecutor();  
        Boolean result = false;     
        Future<Boolean> future = executor.submit(new MyJob("請求引數"));// 將任務提交到執行緒池中     
        try {     
            result = future.get(timeout*1000, TimeUnit.MILLISECONDS);// 設定在2秒的時間內完成   
            System.out.println(result);  
        } catch (InterruptedException e) {  
            System.out.println("執行緒中斷出錯。");  
            future.cancel(true);// 中斷執行此任務的執行緒     
        } catch (ExecutionException e) {     
            System.out.println("執行緒服務出錯。");  
            future.cancel(true);// 中斷執行此任務的執行緒     
        } catch (TimeoutException e) {// 超時異常     
            System.out.println("超時。");     
            future.cancel(true);// 中斷執行此任務的執行緒     
        }finally{  
            System.out.println("執行緒服務關閉。");  
            executor.shutdown();  
        }  
    }  
      
    static class MyJob implements Callable<Boolean> {    
        private String t;  
        public MyJob(String temp){  
            this.t= temp;  
        }  
        public Boolean call() throws InterruptedException {     
            for(int i=0;i<100;i++){  
                if(i==99){  
                    System.out.println(t);  
                }  
                Thread.sleep(3000);
                if (Thread.interrupted()){ //很重要  
                    return false;     
                }  
            }   
            System.out.println("繼續執行..........");     
            return true;     
        }     
    }   
}  

 

相關文章