zoukankan      html  css  js  c++  java
  • 【原创】JAVA并发编程——Callable和Future源码初探

    JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。

     thread和runnable不讨论了。 太多地方可以找到他们的探究了

    重点看callable和future,

    先上一段代码:

    package com.future.chenjun.test;
    
    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;
    
    public class Test {
    
    	public static void main(String[] args) {
    		ExecutorService executorService = Executors.newCachedThreadPool();
    		MyTask myTask = new MyTask();
    		Future<Integer> result = executorService.submit(myTask);
    		executorService.shutdown();
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e1) {
    			e1.printStackTrace();
    		}
    		System.out.println("主线程在执行任务");
    		try {
    			System.out.println("task运行结果" + result.get());
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		} catch (ExecutionException e) {
    			e.printStackTrace();
    		}
    		
    		System.out.println("所有任务执行完毕");
    
    	}
    
    }
    
    class MyTask implements Callable<Integer> {
    
    	@Override
    	public Integer call() throws Exception {
    		System.out.println("子线程在进行计算");
    		Thread.sleep(3000);
    		int sum = 0;
    		for (int i = 0; i < 100; i++)
    			sum += i;
    		return sum;
    	}
    
    }
    

      首先分析main()函数第一行 ,这很重要

    ExecutorService executorService = Executors.newCachedThreadPool();
    自然引出问题1: ExecutorService 本身是一个接口,那
    executorService这个引用到底指向了哪个实现类? 这个问题so easy,直接进JDK源码看结果
    我们看到实现代码如下:
        public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
    

      答案一目了然,根据多态原理无疑这个

    ThreadPoolExecutor 就是 ExecutorService的子类。
    好,这个问题就此打住,记住结论:
     线索1: ThreadPoolExecutor 就是 ExecutorService的子类。
    接下来看main()函数的第三行 : 
    Future<Integer> result = executorService.submit(myTask);

      

    稍微变一下形式,如下
    Future<Integer> result = executorService.submit(new Callable<Integer>(){
        @Override
        public Integer call() throws Exception{
            
        }    
    });
    

      

    look ,和如下代码异曲同工

    new Thread(new Runnable(){
      //匿名内部类实现XXX
      public void run(){
      }
    });

    OK 看一下这个submit到底做了什么事

    我进ThreadPoolExecutor里面一看,卧槽,发现里面没有submit方法,见鬼了

    别急,我翻一下 ThreadPoolExecutor 类声明 

    发现如下声明

    public class ThreadPoolExecutor extends AbstractExecutorService
    

      我好奇的打开抽象类AbstractExecutorService.CLASS的源码,莫非这submit藏在这里了

    打开了。。。。

    终于找到了submit方法,如下

    public <T> Future<T> submit(Callable<T> task) {
      

    if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;

    }

      然后我们自然要搞清楚,这个RunnableFuture是什么鬼,打开它的源码,我们看到:

    public interface RunnableFuture<V> extends Runnable, Future<V> {
        /**
         * Sets this Future to the result of its computation
         * unless it has been cancelled.
         */
        void run();
    }
    

      原来如此,他是Runnable, Future<V>的子接口

    暂时告一段落,理一下思绪



    
    
  • 相关阅读:
    HDU 1525
    kmp模板
    hdu 4616 Game(树形DP)
    hdu 4619 Warm up 2(并查集活用)
    hdu 4614 Vases and Flowers(线段树加二分查找)
    Codeforces 400D Dima and Bacteria(并查集最短路)
    poj 2823 Sliding Window (单调队列)
    hdu 2196 Computer(树形dp)
    hdu 4604 Deque
    最短路径
  • 原文地址:https://www.cnblogs.com/ChenJunHacker/p/5630591.html
Copyright © 2011-2022 走看看