java多线程学习(2)

1)Callable和Future

  

Runnable封装一个异步运行的任务;可以当成一个没有任何参数和返回值的异步方法,Callable和 Runnable类似,但是它有返回值和参数。

  

Callable接口是一个参数化的类型,只有一个方法call。

1 public interface Callable<V>
2 
3 {
4   
5    V call()throws Exception;
6 
7 }

类型参数v是指返回值的类型,例如Callable<Integer>代表最终返回一个Integer类型对象的异步计算。

 

Future保存异步计算的结果。Future接口具有下面的方法:

 1 public interface Future<V>
 2 {
 3   
 4    V get() throws....;
 5 
 6    V get(long timeout, TimeUnit unit) throws...;
 7 
 8    void cancel(boolean mayInterrupt);
 9 
10    boolean isCancelled();
11 
12    boolean isDone();
13 
14 
15 }

第一个get方法的调用将被阻塞,直到计算完成,第二个get方法调用,如果计算完成之前超时,将抛出异常;如果计算还在进行,isdone方法返回false;如果想取消计算,调用cancel方法,如果计算还没开始,将永远也不会开始,如果计算已经开始,那么,如果参数mayInterrupt设为true,则被打断。

 

FutureTask包装器是一种很方便的将Callable转换成Future和Runnable的机制,它同时实现了这两个接口。例如:

 1 Callable<Integer> myComputation=....;
 2 
 3 FutureTask<Integer> task=new FutureTask<Integer>(myComputation);
 4 
 5 Thread t=new Thread(task);//it‘s a Runnable;
 6 
 7 t.start();
 8 
 9 ...
10 
11 Integer result=task.get();//it‘s a Future;

 

2)线程池

构建一个新的线程还是需要一些开销的,如果需要创建大量的生存期很短的线程,那就应该使用线程池,一个线程池包含大量的空闲线程;将一个Runnable对象给线程池,线程池中的一个线程就会调用run方法,当run方法结束之后,该线程并不会死亡,而是继续在池中准备为下一个请求提供服务。

执行器(Executor)类有大量用来构建线程池的静态工厂方法,常用的有以下三个方法:

newCachedThreadPool方法,构建一个线程池,对于任务请求,如果有空闲线程可用,立即让它执行任务,否则就创建一个新线程。

newFixedThreadPool方法,构建一个固定大小的线程池,如果提交的任务大于空闲线程的数量,那么得不到服务的任务将被置于等待队列中。

newSingleThreadExecutor,构建一个大小为1的线程池,由一个线程执行所有任务,一个接一个。

使用方法,例如:

 1 ExecutorService pool=Executors.newCachedThreadPool();
 2 
 3  Callable<Integer> myComputation=....;
 4  
 5  Future<Integer> task=pool.submit(myComputation);
 6 
 7   ...
 8  
 9  Integer result=task.get();
10 
11 pool.shutdown();

 

 

2014-07-22 20:53:08

java多线程学习(2),布布扣,bubuko.com

java多线程学习(2)

上一篇:Java集合类相关面试题


下一篇:从用python做zoj1011发生Non-zero Exit Code错误说起