辐射4118号避难所:a better way to solve the insufficient in TimedRun1可以处理线程中未捕获的异常

来源:百度文库 编辑:九乡新闻网 时间:2024/04/30 09:10:04

 /**
  * 解决TimedRun1中的问题,关键点,任务拥有自己的执行策略,
  * 1.即使任务不响应中断,依靠join方法也能在限时之类返回. 1-0 处
  * 2.解决发生未检查的异常。 2-0 处
  * 1和2两点解决了 TimeRun1不足之处。
  * there have two threads, main tread, taskThread thread of task RethrowableTask.
  * RethrowableTask use the key word of volatile store the Throwable, which guaranteed this variable of
  * Throwable can be visible to share for two thread, main and taskThread.
  * when return the method in the main thread, main thread will check whether there have exception in the
  * subthread. throw it if have.
  * 缺点:
  * 我们并不知道是由于任务自然运行后退出,还是由于join超时退出。 1-0处。
  */
public class TimedRun2 {
    private static final ScheduledExecutorService cancelExec = newScheduledThreadPool(1);

    public static void timedRun(final Runnable r,
                                long timeout, TimeUnit unit)
            throws InterruptedException {
        class RethrowableTask implements Runnable {
            private volatile Throwable t;//can be visible to two thread.

            public void run() {
                try {
                    r.run();
                } catch (Throwable t) {
                    this.t = t;
                }
            }

            void rethrow() {
                if (t != null)
                    throw launderThrowable(t);
            }
        }

        RethrowableTask task = new RethrowableTask();
        final Thread taskThread = new Thread(task);
        taskThread.start();
        cancelExec.schedule(new Runnable() {
            public void run() {
                taskThread.interrupt();
            }
        }, timeout, unit);
        taskThread.join(unit.toMillis(timeout));//1-0
        task.rethrow(); //2-0 check whether have exception in subthread, throw it if have.
    }
}