链接:https://pan.baidu.com/s/1i6FlscH 密码:m21n
任务是一组逻辑执行单元,线程是使得任务异步执行的机制
不可取的所谓线程开启的方式:
1.所有任务放在单个线程中串行执行
2.每一个任务都开启一个线程,无限制,非常浪费资源
有效方法:通过有界队列防止高负荷的应用程序把内存耗尽
使用线程池 java.util.concurrent Executor框架
public interface Executor{
void executor(Runnable command);
}
线程池类型 | 作用 |
---|---|
newFixedThreadPool | 固定长度的线程池,自动维持固定数量的线程 |
newCachedThreadPool | 可缓存的线程池,自动回收空闲的线程,如不足,会新增线程,线程池规模不存在限制 |
newSingleThreadExecutor | 单线程的Executor,保持单线程串行执行 |
newScheduledThreadPool | 固定数量的线程池,延时或者定时执行任务 |
import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class ExecutorTest {
private static final int NUM = 100;
private static final Executor exec = Executors.newFixedThreadPool(NUM);
private static int index=0;
private static int count=0;
public static void main (String[] args) throws IOException {
while(count++ < 100){
Runnable task = new Runnable(){
public void run(){
//TODO
System.out.println(Thread.currentThread().getName() +" :"+index++);
}
};
exec.execute(task);
}
System.exit(1);
}
}
result:
pool-1-thread-1 :0
pool-1-thread-3 :2
pool-1-thread-2 :1
pool-1-thread-4 :3
...
pool-1-thread-98 :97
pool-1-thread-99 :98
pool-1-thread-100 :99
不存在超出100的线程。
状态
接口
public interface ExecutorService extends Executor{
void shutdown(); //平缓关闭,不接受新的任务,完成运行中的任务再关闭
List shutdownNow; //粗暴关闭,尝试关闭所有运行中的任务,不接受新的任务
isTerminated(); //查看线程池是否关闭状态
//....
}
class Demo{
private static final Executor exec = ...
public void start(){
while(!exec.isShutdown){
try{
Runnable task = new Runable(){
public void run(){
//TODO
}
};
exec.execute(task);
}
}catch(RejectExecutorException e){
if(!exec.isShutdown()){
log.info("task rejected",e);
}
}
}
public void stop(){
exec.shutdown();
}
}
Timer类负责管理这类型任务,但表现非常差,缺点如下:
正确使用:
线程池:ScheduledThreadPoolExector
方法: 构造方法 或者 newScheduledThreadPool()
调度服务:
1.DelyQueue(实现 BlockingQueue) 为 ScheduledThreadPoolExector提供调度服务
2.每个Deplyed对象都有一个相应的延迟时间
3.在DelyQueue中,只有某个对象逾期了,才能执行take操作。
Runnable的缺点
Runnable 不能返回一个值或者抛出受检查的异常
接口
public interface Callable{
V call throws Exception; //V == void ,则表示无返回结果
}
public interface Future{
boolean cancel(boolean mayinterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException, CancellationException; //任务完成立刻返回,或者等待任务完成返回,或者抛出异常
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, CancellationException, TimeoutException;
}
使用方式
1.使用Runnable或Callable创建一个实例
2.使用 ExecutorService 的 submit 提交实例 得到 一个 Future
3.通过返回的Future调用相应的方法获得信息
使用页面渲染图像(串行下载)
public class FutureRender{
public static final ExecutorService exec = Executors.newFixedThreadPool(100);
/*
*渲染页面
*/
void renderPage(CharSequence source){
final List imageInfos = scanForImageInfo(source); //获得相关图像的信息
//图片的下载构建任务 V = List
Callable> task = new Callable(){
public List call(){
List result = new ArrayList(); //图像信息
for(ImageInfo imageInfo : result){
result.add(imageInfo.downImage());
}
return result;
}
};
rendTexe(source); //渲染文字
Future> future = exec.submit(task); //获得 Future对象
try{
List imageData = future.get(); //future.get( 指定时间,timeUnit) 限时获得
for(ImageData iamge : imageData){
//渲染图像
}
}catch(InterruptedException e){
//重新设置线程中断状态
Thread.currentThread.interrupt();
//取消任务
future.cancel(true);
}catch(ExecutiontException e){
throw launcherThrowable(e.getCause());
}
}
}
优点:
文字和图片并行处理
缺点:
必须等待所有照片下载完
更高效的并行下载
CompletionService 融合了Executor 和 BlockingQueue
可执行Callable任务
最后通过队列的类似方式获得Future 结果
ExectorCompletionService 实现了CompletionService
1.提交的任务被包装成QueueFuture
2.计算结果放入BlockingQueue
3.方法阻塞,等待所有结果算出
public class Render{
public static final ExecutorService exec = Executors.newFixedThreadPool(100);
/*
*渲染页面
*/
void renderPage(CharSequence source){
final List imageInfos = scanForImageInfo(source); //获得相关图像的信息
CompletionService> completionService = new ExectorCompletionService(exec);
for(ImageInfo iamgeInfo : imageInfos){
completionService.submit(new Callable(){
public ImageDate call(){
return imageInfo.downImage());
}
});
};
rendTexe(source); //渲染文字
Future> future = exec.submit(task); //获得 Future对象
try{
for(int i=0; i future = completionService.take();
ImageData imageData = future.get();
//渲染图片
}
}catch(InterruptedException e){
//重新设置线程中断状态
Thread.currentThread.interrupt();
}catch(ExecutiontException e){
throw launcherThrowable(e.getCause());
}
}
}
1.支持限时返回任务结果
2.invokeAll 参数:一组任务,结果:一组Future,有序
3.某个任务未完成则取消,通过get() 或者isCancelled判断情况
案例:在预定时间内获得旅游网站报价
//报价任务
//TravelQuote 相关公司的报价信息
public class QuoteTask implements Callable{
private final TravelCompany company; //旅游公司
private final TravelInfo travelInfo; //旅游信息条件
public TravelQuote call(){
return company.quote(travelInfo);
}
}
//获得多个公司旅游报价
public List getTravelQuotes(TravelInfo travelInfo, set companies, Comparator ranking, long outtime, TimeUnit unit) throws InterruptedExecption{
List tasks = new ArrayList(); // 任务列表
for(TravelCompany company : companies){
tasks.add(new QuoteTask(company, travelInfo));
}
List> futures = exec.invokeAll(tasks, outtime, unit); //线程池执行报价任务返回future list
List quotes = new ArrayList(tasks.size());
Iterator taskIter = tasks.iterator();
for(Future f : futures){
QuoteTask task = taskIter.next();
try{
quotes.add(f.get());
}catch(ExecutionException e){
quotes.add(task.getFailureQuote(e.getCause()));
}catch(CanellationExecption e){
quotes.add(task.getTimeOutQuote(e));
}
}
Collections.sort(quotes, ranking);
return quotes;
}