首页 > 代码库 > java多线程学习(2)

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