ブロックにタイムアウト制限機能を追加(修正2)


一、背景
製品を作るときに、ある論理にタイムアウトの制限を加える必要があることがわかりましたが、元のブロックはサポートされていませんし、変更することもできません.だから私は外部で包装して、タイムアウトロジックを加える必要があります.
二、分析(修正2)
コードセグメントの実行を制御するには、新しいスレッド(Thread)を開く方法で制御できます.スレッドのタイムアウトを判断するには、符号化量を減らすためにCountDownLatch.await(...)を採用します.メソッドを使用して、非同期の実行スレッドを同期方式に変換します.
論理プロセス:
a、新たに作成したインサートスレッド(Thread)に制限が必要なセグメントを入れてb、Thread構造を実行する場合、new CountDownLatch(1)を設定する.c、インラインスレッドThreadを起動する.start() d、CountDownLatch.awaitは埋め込みスレッド中のlatchがcountDown()e 1、埋め込みスレッドロジックがawaitタイムアウト時間内に完了するのを待つ.countDownを呼び出してawait f、awaitを解放してtrueを返す.実行にタイムアウトe 2がない、埋め込みスレッドロジックがawaitタイムアウト時間内に完了していない(タイムアウト)ことを示す.awaitはfalse g、awaitはfalseを返し、実行にタイムアウトがあることを示す
三、時間制限プログラム補助類(修正2)
TimeoutExecutionタイムアウト制限実行補助クラス.埋め込み実行コードセグメントの戻り値と例外を取得するためにresultとexceptionメンバー変数が追加されました.
package org.noahx.stimeout;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 *          (     ,         )
 * <p/>
 * Created by noah on 6/10/14.
 */
public abstract class TimeoutExecution<T> {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private volatile Exception exception;

    private CountDownLatch latch;

    private T result;

    /**
     *            
     *
     * @return    
     * @throws Exception   
     */
    protected abstract T execute() throws Exception;

    /**
     *       
     *
     * @param timeout       
     * @param unit          
     * @return true,        ,false   
     */
    public boolean execute(int timeout, TimeUnit unit) {
        result = null; //      
        latch = new CountDownLatch(1);
        InnerThread innerThread = new InnerThread(); //         
        innerThread.start();

        boolean isNotTimeout = true;
        try {
            isNotTimeout = latch.await(timeout, unit); //      
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
        }

        if (!isNotTimeout) {
            innerThread.interrupt(); //      
        }

        return isNotTimeout;
    }

    private class InnerThread extends Thread {

        @Override
        public void run() {
            try {
                result = execute(); //      
            } catch (Exception e) {
                exception = e;     //      
            } finally {
                latch.countDown(); //    
            } 
        }

    }

    public T getResult() {
        return result;
    }

    public Exception getException() {
        return exception;
    }
}

[修正1]:TimeoutExecution 2タイムアウト制限実行補助クラス(FutureTaskを使用しても効果は同じ).
package org.noahx.stimeout;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;

/**
 *          (     ,         )
 * <p/>
 * Created by noah on 6/10/14.
 */
public abstract class TimeoutExecution2<T> implements Callable<T> {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private volatile Exception exception;

    private T result;

    /**
     *            
     *
     * @return    
     * @throws Exception   
     */
    protected abstract T execute() throws Exception;

    /**
     *       
     *
     * @param timeout       
     * @param unit          
     * @return true,        ,false   
     */
    public boolean execute(int timeout, TimeUnit unit) {
        result = null; //      
        FutureTask<T> futureTask = new FutureTask<T>(this);

        boolean isNotTimeout = true;
        try {
            new Thread(futureTask).start();
            result = futureTask.get(timeout, unit);
        } catch (InterruptedException e) {
            exception = e;
        } catch (ExecutionException e) {
            exception = (Exception) e.getCause();
        } catch (TimeoutException e) {
            isNotTimeout = false;
        } finally{ // ------[  2]+
            futureTask.cancel(true);  // ------[  2]+
        } 

        return isNotTimeout;
    }

    @Override
    public T call() throws Exception {
        return execute();
    }

    public T getResult() {
        return result;
    }

    public Exception getException() {
        return exception;
    }
}

四、使用補助類(サンプル)
1、TimeoutExampleサンプル類
具体的には注釈を参照し,4つの実行状況をシミュレートした.
package org.noahx.stimeout;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.SimpleLogger;

import java.util.concurrent.TimeUnit;

/**
 * Created by noah on 6/10/14.
 */
public class TimeoutExample {

    static {
        System.setProperty(SimpleLogger.SHOW_DATE_TIME_KEY,"true");
    }

    private static Logger logger = LoggerFactory.getLogger(TimeoutExample.class);

    public static void main(String[] args) {



        logger.info("1:---------------[       ]");
        TimeoutExecution<Void> timeoutExecution1 = new TimeoutExecution<Void>() { //  5s   
            @Override
            protected Void execute() throws Exception {
                logger.info("exe:1");
                return null;
            }
        };
        boolean execute1 = timeoutExecution1.execute(5, TimeUnit.SECONDS);
        printResult(execute1, timeoutExecution1); //  5s   

        logger.info("2:---------------[    ]");
        TimeoutExecution<Void> timeoutExecution2 = new TimeoutExecution<Void>() {
            @Override
            protected Void execute() throws Exception {
                logger.info("exe:2");
                Thread.sleep(10000); //       10s
                return null;
            }
        };
        boolean execute2 = timeoutExecution2.execute(5, TimeUnit.SECONDS);
        printResult(execute2, timeoutExecution2); //  5s   

        logger.info("3:---------------[    ]");
        TimeoutExecution<Integer> timeoutExecution3 = new TimeoutExecution<Integer>() {
            @Override
            protected Integer execute() throws Exception {
                logger.info("exe:3");
                Thread.sleep(1000); //       1s
                return 123;
            }
        };
        boolean execute3 = timeoutExecution3.execute(5, TimeUnit.SECONDS);
        printResult(execute3, timeoutExecution3);

        logger.info("4:---------------[    ,      ]");
        TimeoutExecution<Integer> timeoutExecution4 = new TimeoutExecution<Integer>() {
            @Override
            protected Integer execute() throws Exception {
                logger.info("exe:4");
                Thread.sleep(1000); //       1s
                if (true) {
                    throw new RuntimeException("    ");
                }
                return 123;
            }
        };
        boolean execute4 = timeoutExecution4.execute(5, TimeUnit.SECONDS);
        printResult(execute4, timeoutExecution4);
    }

    private static void printResult(boolean isNotTimeout, TimeoutExecution execution) {
        if (isNotTimeout) {
            logger.info("Ok!!");
            logger.info("result=" + execution.getResult());
            logger.info("e=" + execution.getException());
        } else {
            logger.info("Timeout!!");
            logger.info("result=" + execution.getResult());
            logger.info("e=" + execution.getException());
        }

    }
}

2、出力結果の実行
9 [main] INFO org.noahx.stimeout.TimeoutExample - 1:---------------[       ]
16 [Thread-0] INFO org.noahx.stimeout.TimeoutExample - exe:1
17 [main] INFO org.noahx.stimeout.TimeoutExample - Ok!!
17 [main] INFO org.noahx.stimeout.TimeoutExample - result=null
17 [main] INFO org.noahx.stimeout.TimeoutExample - e=null
17 [main] INFO org.noahx.stimeout.TimeoutExample - 2:---------------[    ]
20 [Thread-1] INFO org.noahx.stimeout.TimeoutExample - exe:2
5020 [main] INFO org.noahx.stimeout.TimeoutExample - Timeout!!
5020 [main] INFO org.noahx.stimeout.TimeoutExample - result=null
5020 [main] INFO org.noahx.stimeout.TimeoutExample - e=null
5020 [main] INFO org.noahx.stimeout.TimeoutExample - 3:---------------[    ]
5025 [Thread-2] INFO org.noahx.stimeout.TimeoutExample - exe:3
6026 [main] INFO org.noahx.stimeout.TimeoutExample - Ok!!
6026 [main] INFO org.noahx.stimeout.TimeoutExample - result=123
6026 [main] INFO org.noahx.stimeout.TimeoutExample - e=null
6026 [main] INFO org.noahx.stimeout.TimeoutExample - 4:---------------[    ,      ]
6032 [Thread-3] INFO org.noahx.stimeout.TimeoutExample - exe:4
7032 [main] INFO org.noahx.stimeout.TimeoutExample - Ok!!
7032 [main] INFO org.noahx.stimeout.TimeoutExample - result=null
7032 [main] INFO org.noahx.stimeout.TimeoutExample - e=java.lang.RuntimeException:     

五、ソースのダウンロード
http://1drv.ms/1zHq3Oe