Lambda表达式之并行和并发
并行和并發是個非常大的概念,也不是一篇文章能夠完全的包含,所以這邊只能簡要概括如何通過Lambda表達式來實現。
?
首先并行和并發是兩個不同的概念:
并行英文叫Parallelism,理想情況下,每個線程擁有自己獨立的cpu核心,像平行線一樣的各自執行自己的任務,多用于CPU密集型的任務;
并發英文叫Concurrency,每個線程不一定擁有獨立的cpu核心,每次的執行時間點和執行時間長度由系統調度決定,多用于處理io阻塞型的任務。
?
不恰當的并行或并發編程會降低系統的處理效率。
?
Lambda實現并行編程很容易:
1. 集合可以通過parallelStream()方法獲取擁有并行處理能力的Stream;
2. Stream可以通過parallel()方法標記你希望以并行的方式處理。
?
double sum = IntStream.range(1, 1000000).asDoubleStream().parallel().map(x -> Math.sin(x) * Math.sin(x) + Math.cos(x) * Math.cos(x)).sum();?
并行處理的Stream會自行處理鎖的問題,所以不要在沒有把握的時候自行加鎖,尤其要注意有些方法自帶synchronized,并行的效果反而沒有順序執行(sequential)好。
refer?Java 8 Stream parallel performance and CPU resource consumption seems really poor compared to serial
?
關于并發,可以參閱最近比較火的響應式編程
http://reactivex.io/
?
這邊簡要的寫個示例:根據iteye用戶的rss,來輸出博客的標題和鏈接
class Item {public String title;public String link; }?解析rss
static List<Item> retrieveTitleNLink() {List<Item> list = new LinkedList<>();try {URL url = new URL("http://xuanzhui.iteye.com/rss");HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.addRequestProperty("user-agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36");BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder documentBuilder = factory.newDocumentBuilder();Document document = documentBuilder.parse(inputStream);NodeList itemList = document.getDocumentElement().getElementsByTagName("item");for (int i = 0; i < itemList.getLength(); i++) {Node node = itemList.item(i);NodeList itemChildren = node.getChildNodes();Item item = new Item();for (int j = 0; j < itemChildren.getLength(); j++) {Node child = itemChildren.item(j);if (child.getNodeName().equalsIgnoreCase("title"))item.title = child.getTextContent();if (child.getNodeName().equalsIgnoreCase("link"))item.link = child.getTextContent();}list.add(item);}} catch (IOException | ParserConfigurationException | SAXException e) {e.printStackTrace();}return list; }?接下來是比較核心的代碼,先看一下直接用匿名類的寫法
public static void main(String[] args) throws IOException {Observable.create(new Observable.OnSubscribe<Item>() {@Overridepublic void call(Subscriber<? super Item> subscriber) {// 要做的就是不斷向注冊者發送數據List<Item> list = retrieveTitleNLink();for (int i = 0; i < list.size(); i++)subscriber.onNext(list.get(i));}}).subscribeOn(Schedulers.io()).subscribe(new Action1<Item>() {@Overridepublic void call(Item item) {// 要做的就是不斷處理上面發送的數據System.out.println("title: " + item.title);System.out.println("link: " + item.link);System.out.println("*********************");}});System.out.println("should print immediately without being blocked ?");// 這邊只是為了主進程等待io進程結束System.in.read(); }?要重點關注subscribeOn(Schedulers.io()),表示新開一個io的進程處理網絡請求。
?
然后再看Lambda表達式的寫法
public static void main(String[] args) throws IOException {Observable.create(subscriber -> retrieveTitleNLink().forEach(subscriber::onNext)).subscribeOn(Schedulers.io()).map(item -> {Item tmp = (Item) item;return tmp.title + " ====>>> " + tmp.link;}).subscribe(System.out::println);System.out.println("should print immediately without being blocked ?");// 這邊只是為了主進程等待io進程結束System.in.read(); }?更詳細的用法還得看相關文檔。
?
?
?
?
總結
以上是生活随笔為你收集整理的Lambda表达式之并行和并发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: $.toJSON的使用方法
- 下一篇: 遥控助手-支持蓝牙、红外、WIFI、投屏