Future方式中断线程实现

来源:互联网 发布:淘宝直通车图片大小 编辑:程序博客网 时间:2024/05/21 09:28

测试代码

代码如下

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 ThradPoolTest {    private static ExecutorService executor = Executors.newCachedThreadPool();    protected static int SLEEP_TIME = 2000;    /**     * @param args     */    public static void main(String[] args) {        Boolean result =null;        Future<Boolean> timeOutfuture = executor.submit(new TestJob(SLEEP_TIME*2));        System.out.println("==========timeOutfuture  test==============");        try {            result = timeOutfuture.get(SLEEP_TIME, TimeUnit.MILLISECONDS);        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        } catch (TimeoutException e) {            System.out.println("Time is out");            timeOutfuture.cancel(true);        }        System.out.println(result);         Future<Boolean> normalFuture = executor.submit(new TestJob(SLEEP_TIME/2));        System.out.println("==========normalFuture future test==============");        try {            result = normalFuture.get(SLEEP_TIME, TimeUnit.MILLISECONDS);        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        } catch (TimeoutException e) {            System.out.println("Time is out");            normalFuture.cancel(true);        }        System.out.println(result);         executor.shutdown();     }    // 实现Callable接口    static class TestJob implements Callable<Boolean> {        private int workTime;        public TestJob(int workTime){            this.workTime = workTime;        }        @Override        public Boolean call() {            long startTime = System.currentTimeMillis();            while(true){                for (; System.currentTimeMillis() - startTime < workTime; ) {                    doSomeThing();                    //判断是否中断                    if (Thread.interrupted()){                        return false;                     }                }                //任务完成返回                return true;            }        }        //进行必要的处理        public void doSomeThing(){}    }

说明:实际上在doSomeThing的方法的实现也很重要,如果这个地方完全阻塞,那么实际上到不了Thread.interrupted()检测的这个方法,线程无法中断。

JDK FutureTask的canel分析

    public boolean cancel(boolean mayInterruptIfRunning) {        if (state != NEW)            return false;        if (mayInterruptIfRunning) {            if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))//NEW设置为INTERRUPTING状态                return false;            Thread t = runner;            if (t != null)                t.interrupt();            UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state,设置为INTERRUPTED        }        else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))//如果已经INTERRUPTED,返回false            return false;        finishCompletion();//完成收尾工作        return true;    }

说明
1. finishCompletion通知相关waiters进行unpark
2. waiters为future的一个成员变量,Future中的get方法,将当前的线程增加到waiters中,并park自己
3. waiters为FutureTask中的一个成员变量,为等待队列的队列头

参考文档

http://stackoverflow.com/questions/17233038/how-to-implement-synchronous-method-timeouts-in-java
http://stackoverflow.com/questions/2275443/how-to-timeout-a-thread

1 0
原创粉丝点击