Java多线程--FutureTask

异步执行任务,处理其他的事情,然后获取返回结果。
案例:异步去做蛋糕,然后去做其他事情,做完其他事情然后去取蛋糕。

public static void main(String[] args) throws InterruptedException,
			ExecutionException {

		Callable<Integer> call = new Callable<Integer>() {
			@Override
			public Integer call() throws Exception {
				System.out.println("正在做蛋糕");
				Thread.sleep(3000);
				return 1;
			}
		};

		FutureTask<Integer> task = new FutureTask<Integer>(call);
		Thread thread = new Thread(task);
		thread.start();

		// do something

		System.out.println(" 干点别的。。。");

		// 去取蛋糕
		Integer result = task.get();
		System.out.println("拿到的结果为:" + result);
	}

案例:

@Test
    public void testFuture02() {
        List<Future> lstFuture = new ArrayList<>();
        lstFuture.add(executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Thread.sleep(5000);
                return 1;
            }
        }));
        lstFuture.add(executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                Thread.sleep(1000);


                return 0;
            }
        }));
        for (int i = 0; i < lstFuture.size(); i++) {
            Future future = lstFuture.get(i);
            if (future.isDone()) {
                try {
                    new Thread();
                    logger.info("返回结果:{}", future.get());
                } catch (InterruptedException e) {
                    logger.error("执行的任务被打断,异常信息{}",e);
                } catch (ExecutionException e) {
                    logger.error("任务执行时出现异常,异常信息{}",e);
                }
                continue;
            } else {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                i--;
            }
        }
    }

添加两个任务到线程池中执行,主线程去获取执行结果。

源码解析

    public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    //CAS设置执行的状态由NEW改为COMPLETING,设置结果后,改为NORMAL状态
                    //唤醒链表中的每一个线程
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

get

    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            //任务还没执行完成,当前线程构造一个等待节点,添加到的链表的末尾。
            s = awaitDone(false, 0L);
        return report(s);
    }
    private int awaitDone(boolean timed, long nanos)
        throws InterruptedException {
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
        WaitNode q = null;
        boolean queued = false;
        for (;;) {
            if (Thread.interrupted()) {
                //等待线程设置了中断标识,从链表中移除
                removeWaiter(q);
                throw new InterruptedException();
            }

            int s = state;
            if (s > COMPLETING) {
            	//已经执行完成
                if (q != null)
                    q.thread = null;
                return s;
            }
            else if (s == COMPLETING) // cannot time out yet
                //马上执行完成,让CPU重新调度一下,
                Thread.yield();
            else if (q == null)
                //构造等待节点
                q = new WaitNode();
            else if (!queued)
                //没有入链表中
                queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                     q.next = waiters, q);
            else if (timed) {
                //超时处理
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L) {
                    removeWaiter(q);
                    return state;
                }
                LockSupport.parkNanos(this, nanos);
            }
            else
                LockSupport.park(this);
        }
    }

去除已经放弃的节点

    private void removeWaiter(WaitNode node) {
        if (node != null) {
            // 线程指向空
            node.thread = null;
            retry:
            for (;;) {          // restart on removeWaiter race
                for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
                    s = q.next;if (q.thread != null)
                        pred = q;
                    else if (pred != null) {
                        //如果当前节点q线程指向为空,说明已经被放弃,并且前面有节点,
                        //当前节点q抛弃
                        pred.next = s;
                        if (pred.thread == null) // check for race
                            //前面节点也线程置为空,那么就重新开始检测。
                            continue retry;
                    }
                    // 前面不存在节点,当前节点已经放弃,那么将头节点设置为s。
                    else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                          q, s))
                        //重新开始检测。                 
                        continue retry;
                }
                break;
            }
        }
    }

ExecutorCompletionService

    public static <T> List<T> getCompletionServiceResult(Executor executor, List<Callable<T>> callableList, long totalTimeOutMillisSecond,
                                                         long singleTimeOutMillsSecond) {
        long beginTime = System.currentTimeMillis();
        logger.info("提交任务个数{}", callableList.size());
        CompletionService<T> completionService = new ExecutorCompletionService<>(executor);
        List<Future<T>> futureList = new ArrayList<>(callableList.size());
        List<T> resultList = new ArrayList<>();
        try {
            for (Callable<T> callable : callableList) {
                futureList.add(completionService.submit(callable));
            }
            long endTime = System.currentTimeMillis() + totalTimeOutMillisSecond;
            for (int i = 0; i < callableList.size(); ++i) {
                try {
                    if (endTime < System.currentTimeMillis()) {
                        //已经超时,直接快速获取
                        logger.warn("全局时间已经超时");
                        Future<T> future = completionService.poll();
                        if (future == null) {
                            logger.warn("超时获取为空,放弃后面任务");
                            //放弃后面超时的
                            break;
                        } else {
                            resultList.add(future.get());
                        }
                    } else {
                        //正常获取
                        Future<T> future = completionService.poll(singleTimeOutMillsSecond, TimeUnit.MILLISECONDS);
                        if (future != null) {
                            resultList.add(future.get());
                        } else {
                            logger.error("获取结果超时");
                        }
                    }
                } catch (Exception e) {
                    logger.error("任务执行异常", e);
                }
            }
        } finally {
            for (Future<T> future : futureList) {
                future.cancel(true);
            }
        }
        logger.info("提交任务耗时{}秒", (System.currentTimeMillis() - beginTime) / 1000);
        return resultList;
    }

ExecutorCompletionService里面维持一个队列,线程池中的任务执行完了就存放到队列中。主要是在done方法中。

    private class QueueingFuture extends FutureTask<Void> {
        QueueingFuture(RunnableFuture<V> task) {
            super(task, null);
            this.task = task;
        }
        protected void done() { completionQueue.add(task); }
        private final Future<V> task;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值