渲染器
1.newFixedThreadPool。newFixedThreadPool将创建一个固定长度的线程池,每当提交一个任务时创建一个线程,直到达到线程池的最大数量,这时线程池的规模将不再变化(如果某个线程由于发生了未预期的Exception而结束,那么线程池会补充一个新的线程)。
2.newcachedThreadPool。newCachedThreadPool将创建一个可缓存的线程池,如果线程池的当前规模超过了处理需求时,那么将回收空闲的线程,当需求增加时,则可以添加新的线程,线程池的规模不存在任何限制。
3.newSingleThreadExecutor。newSingleThreadExecutor是一个单线程的Executor,它创建单个工作者线程来执行任务,如果这个线程异常结束,会创建另一个线程来替代。newSingleThreadExecutor能确保依照任务在队列中的顺序来串行执行(例如FIFO,LIFO,优先级)。
4.newscheduledThreadPool。newScheduledThreadPool创建一个固定长度的线程池,而且以延时或定时的方式执行任务,类似于Timer。
注意:Timer支持基于绝对时间而不是相对时间的调度机制,因此任务的执行对系统时钟变化很敏感,而scheduledthreadpoolexecutor只支持基于相对时间的调度。
5.下面看一下第一种使用Future来实现页面渲染器
分析:创建一个Callable来下载所有的图像,并将其提交到一个ExecutorService。这将返回一个描述任务执行情况的Future。当主任务需要图像时,他会等待Future.get的调用结果。如果幸运的话,当开始请求时所有的图片就已经下载完成了,即使没有,至少图像的下载任务也已经提前开始了。
public abstract class FutureRenderer {
private final ExecutorService executor = Executors.newCachedThreadPool();
void renderPage(Charsequence source) {
final List<ImageInfo> imageInfos = scanforImageInfo(source);
Callable<List<ImageData>> task = new Callable<List<ImageData>>() {
@Override
public List<ImageData> call(){
List<ImageData> result = new ArrayList<>();
for(ImageInfo info:imageInfos) {
result.add(info.downLoadImage());
}
return result;
}
};
//提前提交获取图片信息的数据
Future<List<ImageData>> future = executor.submit(task);
//开始渲染文本
renderText(source);
try {
List<ImageData> imageDatas = future.get();
for(ImageData data:imageDatas) {
//开始渲染图片
renderImage(data);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Thread.currentThread().interrupt();
future.cancel(true);
} catch (executionException e) {
e.getCause();
}
}
//图片数据
interface ImageData{
}
//图片信息
interface ImageInfo{
ImageData downLoadImage();
}
//渲染文本
abstract void renderText(CharSequence s);
//得到所需图片的信息
abstract List<ImageInfo> scanForImageInfo(CharSequence s);
//渲染图片
abstract void renderImage(ImageData i);
}
缺点:用户必须等所有的图像都下载完成后,才能显示出来。对用户的体验是够有好。下面我们优化一下,做到每当下载完一幅图像就立刻显示出来。
(二)CompletionService与blockingqueue
CompletionService将Executor和BlockingQueue的功能融合在一起。可以将Callable任意任务提交给他执行,然后使用类似于队列的操作take和poll等方法来获得以完成的结果(take和poll方法会在得出结果之前阻塞),而这些结果会在完成时将被封装为Future。
改进之后的写法如下
public abstract class Renderer {
private final ExecutorService executor;
public Renderer(ExecutorService executor) {
this.executor = executor;
}
void renderPage(CharSequence source) {
final List<ImageInfo> info= scanForImageInfo(source);
CompletionService<ImageData> completionService = new ExecutorCompletionService<>(executor);
for(final ImageInfo imageInfo:info) {
completionService.submit(new Callable<Renderer.ImageData>() {
@Override
public ImageData call() throws Exception {
// TODO Auto-generated method stub
return imageInfo.downloadImage();
}
});
}
renderText(source);
for(int t = 0,n = info.size();t < n;t++) {
try {
Future<ImageData> f = completionService.take();
ImageData imageData = f.get();
renderImage(imageData);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}catch (ExecutionException e) {
e.getCause();
}
}
}
interface ImageData{
}
interface ImageInfo{
ImageData downloadImage();
}
abstract void renderText(CharSequence s);
abstract List<ImageInfo> scanForImageInfo(CharSequence s);
abstract void renderImage(ImageData i);
}
相关阅读
VRay 3.6 for 3ds Max 2018渲染器64位汉化安装教程+破
V-Ray3.6是一款由专业的渲染器开发公司CHAOSGROUP开发的渲染软件,VRay是目前业界最受欢迎的渲染引擎,可以完美地集成到每个3D艺术家
VRay 3.6 for Rhino6渲染器汉化破解安装教程(附下载)
VRay 3.6 for Rhino是一款专为Rhino(犀牛)6.0用户打造的增强渲染器插件,它是一款三维建筑可视化必备渲染器,创建更好的渲染图像比以前
vray3.4 for sketchup 2017 64位渲染器安装图文教程、
vray for sketchup是一套将vray整合嵌置于sketchup之内的工具,vray for sketchup成功的沿袭了sketchup的日照和贴图习惯。使得方案