了解给定代码的代码执行路径

时间:2014-04-09 12:37:44

标签: java java.util.concurrent

我是Java的新手,任何人都可以解释一下,在下面给出的代码中,哪个方法调用了call方法, 还帮助我理解代码的代码执行路径:

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
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 MyCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        Thread.sleep(1000);         
        return Thread.currentThread().getName();
    }

    public static void main(String args[]){
        //Get ExecutorService from Executors utility class, thread pool size is 10
        ExecutorService executor = Executors.newFixedThreadPool(10);            
        List<Future<String>> list = new ArrayList<Future<String>>();            
        Callable<String> callable = new MyCallable();

        for(int i=0; i< 100; i++){              
            Future<String> future = executor.submit(callable);              
            list.add(future);
        }

        for(Future<String> fut : list){
            try {               
                System.out.println(new Date()+ "::"+fut.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }           
        executor.shutdown();
    }
}

3 个答案:

答案 0 :(得分:1)

在此代码中,您使用的是Executor和ThreadPool。 executor.submit(callable)使执行程序将您的Callable放入池中的一个线程,并通过运行call()方法启动此线程。要了解此代码,您应该阅读theese三个站点:

可赎回:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

ThreadPool:http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html

执行人:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html

答案 1 :(得分:1)

代码向包含10个线程的Callable提交ExecutorService 100次,并捕获指示每个Callable运行时间的Futures。

ExecutorService executor = Executors.newFixedThreadPool(10);            
List<Future<String>> list = new ArrayList<Future<String>>();            
Callable<String> callable = new MyCallable();

for (int i = 0; i < 100; i++)
{              
  Future<String> future = executor.submit(callable);              
  list.add(future);
}

一旦10个线程中的每个线程都运行Callable,剩余的Callables将排队并在每个线程可用时运行。

在添加了所有Callables之后,下一个代码块从每个Future获取结果,重要的是调用线程将阻塞对Future.get的调用,直到Callable结束,因此结果将是按照添加Callables的顺序打印。

for(Future<String> fut : list)
{
  try 
  {               
    System.out.println(new Date() + "::" + fut.get());
  } 
  catch (InterruptedException | ExecutionException e) 
  {
    e.printStackTrace();
  }
}     

最后,执行程序将关闭以终止它包含的线程。

executor.shutdown();

答案 2 :(得分:0)

当调用executor.sumbit(callable);时,异步任务将与当前线程并行启动,以调用所提供的call()的{​​{1}}方法。 &#34;并行&#34;这里,表示由Callable创建的线程池的10个线程之一。

您当前的线程(在Executors.newFixedThreadPool(10);中)继续前进,这样做了一百次(如果所有10个线程都已忙,则main()会排队。

要检索每个调用的结果,您必须使用Callable给出的每个Future对象,submit。此get()将等待相应的fut.get()完成,并返回通话结果。