国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java并發編程實踐(讀書筆記) 任務執行(未完)

2019-11-14 22:47:29
字體:
來源:轉載
供稿:網友
java并發編程實踐(讀書筆記) 任務執行(未完)任務的定義

大多數并發程序都是圍繞任務進行管理的.任務就是抽象和離散的工作單元.

任務的執行策略

1.順序的執行任務

這種策略的特點是一般只有按順序處理到來的任務.一次只能處理一個任務,后來其它任務都要等待處理.響應性很糟糕,吞吐量低.系統資源利用率低.

2.顯示的為任務創建線程

為每個任務創建對應一個線程,響應快,系統資源利用路高.缺點是資源消耗量大,如果有大量任務要執行的話,系統遲早會因為無限制創建過多的線程而造成內存耗盡.特別當創建的線程數量遠遠大于系統的CPU核數,由于每一個核同一時刻只能執行一個線程,所以系統要執行很多不必要的線程上下文切換,造成資源大量浪費.

3.Executor框架

Executor接口本身很簡單,就一個execute方法.但是由Executor這個接口衍生出來的類,功能非常強大.可以這么認為,Executor框架這是線程管理的工具.可以對線程的生命周期和執行策略進行管理.

Executor接口

public interface Executor {    void execute(Runnable command);}

Executor框架是靠ThreadPoolExecutor實現的,簡單理解為是一個線程池.其實是通過線程池和一個阻塞隊列BlockingQueue<Runnable>對線程進行管理.

頁面渲染器實例


該實例要實現2個任務,第一是渲染文本(速度快),第二個是渲染圖片(速度慢).渲染圖片的時候要先下載圖片才能渲染.

1.第一種方式:順序執行頁面渲染

public class SingleThreadRenderer {    public void renderPage(CharSequence source) {        renderText(source);// 處理文本,速度快        List<ImageData> imageData = new ArrayList<>();        for (ImageInfo info : scanForImageInfo(source)) {            imageData.add(info.downloadImage());// 下載圖片,速度慢        }        for (ImageData data : imageData) {            renderImage(data);// 處理圖片        }    }}

這種實現方式簡單,但是缺點也很明顯,就是渲染文本和渲染圖片不能并發執行,CPU利用率低.

2.第二種方式:使用Future實現頁面渲染器

Future可以持有異步并發線程的執行結果,Executors可以對線程執行并發操作.

public class FutureRenderer {    PRivate final ExecutorService exec = Executors.newFixedThreadPool(Runtime            .getRuntime().availableProcessors());    public void renderPage(CharSequence source) {        final List<ImageInfo> imageInfos = scanForImageInfo(source);        Callable<List<ImageData>> task = new Callable<List<ImageData>>() {            public List<ImageData> call() throws Exception {                List<ImageData> imageData = new ArrayList<>();                for (ImageInfo info : imageInfos) {                    imageData.add(info.downloadImage());// 下載圖片,速度慢                }                return imageData;            }        };        Future<List<ImageData>> f = exec.submit(task);        //渲染圖片的線程正在執行的同時處理文本任務        renderText(source);// 處理文本,速度快        try {            List<ImageData> imageDatas = f.get();            for (ImageData data : imageDatas) {                renderImage(data);// 處理圖片            }        } catch (InterruptedException | ExecutionException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

這種執行策略仍舊有局限性,這是由于并行運行異類任務并不會獲得好的性能.只有大量相互獨立的且同類的任務進行并發處理,才能獲得真正性能提升.

3.第三種方式:使用CompletionService的頁面渲染器

public class CompletionServiceRenderer {    private final ExecutorService exec = Executors.newFixedThreadPool(Runtime            .getRuntime().availableProcessors());    public void renderPage(CharSequence source) {        final List<ImageInfo> imageInfos = scanForImageInfo(source);        CompletionService<ImageData> completionService = new ExecutorCompletionService<>(                exec);        for (final ImageInfo info : imageInfos) {            Callable<ImageData> task = new Callable<ImageData>() {                public ImageData call() throws Exception {                    return info.downloadImage();                }            };            completionService.submit(task);        }        renderText(source);// 處理文本,速度快        for (int i = 0; i < imageInfos.size(); i++) {            try {                Future<ImageData> future = completionService.take();                ImageData imageData = future.get();                renderImage(imageData);// 處理圖片            } catch (InterruptedException | ExecutionException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}

?這種方式不用等下載所有圖片才處理,而是每下載一張圖片就處理,實現了很好的并發行.


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 松江区| 宁国市| 祁门县| 嘉禾县| 陵水| 新乐市| 含山县| 新晃| 留坝县| 吕梁市| 泰州市| 鹿泉市| 乌鲁木齐县| 循化| 康马县| 望都县| 西藏| 彭山县| 荥阳市| 铜鼓县| 繁峙县| 合山市| 林西县| 城固县| 惠水县| 龙游县| 葫芦岛市| 天祝| 开鲁县| 肥乡县| 隆化县| 三都| 达州市| 富源县| 衡阳市| 株洲市| 固安县| 乡宁县| 永宁县| 建阳市| 蒙山县|