Future方式中断线程实现

测试代码

代码如下

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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小她爹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值