門多西諾複合大火續燒 面積相當於洛杉磯市

摘錄自2018年8月8日中央通訊社台北報導

美國加州野火繼續傳出災情,「門多西諾複合大火」延燒面積已相當於整個洛杉磯市,上萬名消防員今天仍不斷努力救災控制火勢,上月爆發的一連串野火已造成11人喪命。

加州北部的門多西諾複合大火(Mendocino Complex Fire)由2個分別名為「河流」(River fire)及「牧場」(Ranch fire)的野火組成,延燒面積已達29萬英畝(11萬7359公頃),大小相當於整個洛杉磯市。

門多西諾複合大火昨天(7日)改寫短短8個月前「湯瑪斯野火」(Thomas Fire)紀錄,成為加州有紀錄以來最大野火。湯瑪斯野火去年12月在南加州肆虐,延燒面積達28萬1893英畝。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

蓄意污染亞馬遜雨林 雪佛龍在厄瓜多憲法法庭敗訴

環境資訊中心外電;姜唯 翻譯;林大利 審校;稿源:ENS

美國雪佛龍(Chevron)公司的世紀污染訴訟案,有了最新進展。厄瓜多憲法法庭稍早駁回了雪佛龍對95億美元污染判決的最終上訴,認定該公司蓄意將數十億加侖的有毒油廢料傾倒在亞馬遜熱帶雨林的原民土地上。

長達151頁的判決書中,以8比0一致判定原告原民團體勝訴,並駁回了雪佛龍的所有說法,例如雪佛龍自己也是詐欺受害者,以及厄瓜多法院對此案無管轄權等都遭到駁回。

前油田運營商德士古(後被雪佛龍收購)蓄意將數十億加侖的有毒油廢料傾倒在亞馬遜熱帶雨林。圖片來源:Caroline Bennett / Rainforest Action Network

環境集體訴訟案 第四次獲勝

厄瓜多憲法法院僅審理憲法問題,是厄瓜多第三大上訴法院,也是該國第四個維持2011年判決結果的法院,連同厄瓜多最高民事法庭和國家法院一致裁定雪佛龍須做出鉅額賠償。

這個針對雪佛龍公司的集體訴訟案,判決書於7月11日發布,原告是守護亞馬遜陣線(Frente de Defensa de la Amazonia),代表厄瓜多亞馬遜北部地區80個原民和農民社區的草根團體。

該訴訟最初由約3萬名熱帶雨林村民於1993年在紐約聯邦法院提出,被告是前油田運營商德士古(Texaco,已被雪佛龍公司收購)。2001年雪佛龍公司接受厄瓜多具有管轄權後,一名美國聯邦法官將此案移交給厄瓜多法院。

「這個判決是厄瓜多人民20年來為了爭取環境正義,對抗世界級污染者、流氓企業的再一次巨大勝利,」環保金人獎得主、1993年訴訟案起草者楊澤(Luis Yanza)表示。他目前也是守護亞馬遜陣線的主席。

楊澤說:「在雪佛龍開始賠償厄瓜多人民前,任何國家都不應該與雪佛龍做生意。」

致癌油廢料污染 雪佛龍八年拖延纏訟

厄瓜多首席律師薩拉查(Patricio Salazar)表示,「司法已認定雪佛龍非法攻擊代表原住民社群的律師,而不是根據是非來訴訟。雪佛龍現在極有可能必須全額支付賠償金,因為它在法律上和道德上都有義務這樣做。」

厄瓜多初審法院依據105份技術證據報告,在2011年判決該公司致癌油廢料污染了1500平方英里的亞馬遜土地。但是八年來,雪佛龍以拖延戰術因應訴訟。

生活在熱帶雨林中的數千人,包括許多原住民,已經死於癌症,而成千上萬的人必須忍受這場世界級的公衛災難。

代表厄瓜多村民的美國律師唐齊格(Steven Donziger)。圖片來源:Steven Donziger

拒支付賠償金 村民仍沒有醫療

收受雪佛龍公司400口油井特許使用費的厄瓜多政府,沒有給受害者太大幫助。

哈佛大學畢業,代表厄瓜多村民的美國律師唐齊格(Steven Donziger)曾走訪受影響地區數十次,他表示受影響地區並沒有醫療服務,許多人甚至一次醫生都沒看,也沒接受任何治療就死於癌症。

「雪佛龍在厄瓜多引發了一場史無前例的人道主義危機。再不清除污染,未來幾年將有數萬人死亡。全世界都必須關注,雪佛龍的股東和管理層必須立即採取行動,解決這個日益嚴重的問題。」唐齊格說。

雪佛龍多年來一直拒絕支付判決賠償金,目前連本帶利已經來到120億美元(約新台幣1361億元)。

雪佛龍公司人員甚至威脅原民,若繼續堅持訴訟,他們可和原告「終身纏訟」。

卡普蘭法官 採信偽證風波

這份最新判決也是對美國紐約南區地方法院法官卡普蘭(Lewis A. Kaplan)的重大打擊。

2014年,這位具有爭議性的法官僅憑一位承認收賄的雪佛龍證人的假證詞便裁定,厄瓜多最高法院對雪佛龍提出的95億美元賠償判決是透過欺詐和脅迫手段取得。卡普蘭拒絕讓公正的事實調查員陪審團參與,也拒絕考量任何有關雪佛龍污染厄瓜多環境的證據。

但新事證顯示,雪佛龍支付厄瓜多前法官格拉(Alberto Guerra)大筆賄款之後,卡普蘭的判決被推翻。雪佛龍幫助格拉一家搬到美國後,格拉承認在雪佛龍律師的指導下作偽證。

卡普蘭僅憑格拉的偽證做出判決,也是全世界唯一做出有利雪佛龍判決的法官。

「出於省錢的錯誤營運決策」 法庭定調蓄意污染

基於比卡普蘭所能取得更完整的證據,17名厄瓜多法官作出有利厄瓜多村民的判決。12名加拿大法官,包括該國最高法院,也針對多個技術性問題作出有利厄瓜多村民的判決。

厄瓜多憲法法庭強調,雪佛龍污染環境造成嚴重後果不是意外造成,而是處心積慮為公司和股東省錢的運營決策,加上20年來蓄意拖延的額外罪行所導致。

厄瓜多原告也在加拿大法院取得了幾項上訴勝利,他們在加國蒐集雪佛龍資產,以迫使其遵守厄瓜多的判決。

Chevron Defeated in Ecuador’s Constitutional Court QUITO, Ecuador, July 31, 2018 (ENS)

In a benchmark pollution case, Ecuador’s Constitutional Court has rejected Chevron’s final appeal of a $9.5 billion pollution judgment that found the company deliberately dumped billions of gallons of toxic oil waste onto Indigenous lands in the Amazon rainforest.

Photo: Caroline Bennett / Rainforest Action Network

The unanimous 8-0 decision, issued in a 151-page document published July 11, was a total victory for the Indigenous groups that brought the case and a rejection of all of Chevron’s claims.

The Court rejected Chevron’s allegations that it was victimized by fraud, and the court threw out the company’s claim that Ecuadorian courts had no jurisdiction over the matter.

Ecuador’s Constitutional Court, which deals only with Constitutional issues, is the third major appellate court in Ecuador and the fourth court overall in the country to uphold the trial-level decision against Chevron, which was issued in 2011. Ecuador’s highest civil court, the National Court of Justice, has ruled unanimously to affirm the judgment against Chevron.

The class action case against Chevron was spearheaded by the Frente de Defensa de la Amazonia, the Amazon Defense Front, a grassroots group representing 80 Indigenous peoples and farmer communities in Ecuador’s northern Amazon region.

The case was originally filed in 1993 in federal court in New York against the former oil field operator Texaco, now part of Chevron Corporation, on behalf of an estimated 30,000 rainforest villagers. But in 2001 a U.S. federal judge moved it to Ecuador’s courts at Chevron’s request after the company accepted jurisdiction there.

“This decision is another huge victory for the people of Ecuador in their historic two-decade battle for environmental justice against the world’s worst corporate polluter and rogue operator,” said Luis Yanza, a Goldman Prize winner who initiated the lawsuit against Chevron in U.S. federal court in 1993, and serves as president of the Frente de Defensa de la Amazonia, Amazon Defense Front.

“No country should ever do business with Chevron until the company first pays for the harm it caused to the people of Ecuador,” Yanza said.

Patricio Salazar, the lead Ecuadorian lawyer on the case, said, “Justice has prevailed over Chevron’s illegal attempts to engage in constant attacks on lawyers who defend the Indigenous communities rather than litigate in good faith on the merits. It is now highly likely that Chevron will pay every last dollar of the judgment against it, as it is legally and ethically obligated to do.”

After eight years of proceedings slowed by Chevron’s strategy of deliberate delay, Ecuador’s trial court relied on 105 technical evidentiary reports to find in 2011 that the company poisoned a 1,500 square mile area of the Amazon with carcinogenic oil waste.

Thousands who live in the rainforest, including many Indigenous peoples, have died of cancer while tens of thousands must endure what is one of the world’s worst ongoing public health catastrophes.

Photo: Jonathan McIntosh / Rainforest Action Network

Ecuador’s government, which received royalties from Chevron’s operation of 400 well sites, has been of little help to the victims. Medical care in the affected region is non-existent, and many people perish from cancer without even visiting a doctor and after receiving no treatment, said Steven Donziger, the Harvard educated U.S. legal representative of the Ecuadorian communities, who has taken dozens of trips to the affected area.

“Chevron has caused a humanitarian crisis in Ecuador of epic proportions that is ongoing to this day,” he said. “Tens of thousands of people will die in the coming years if nothing is done to clean up the pollution. The world must pay attention and Chevron shareholders and management must act immediately to address this worsening problem.”

Chevron has refused for years to pay the Ecuador judgment, now worth $12 billion with interest. Company officials have threatened the Indigenous groups with a “lifetime of litigation” if they persist.

The latest Ecuadorean court decision is also a major blow to controversial Judge Lewis A. Kaplan, a judge of the U.S. District Court for the Southern District of New York.

In 2014, Judge Kaplan ruled that the $9.5 billion Lago Agrio judgment leveled against Chevron by Ecuador’s highest court, was obtained by way of fraud and coercion.

Kaplan relied on false testimony from an admittedly corrupt Chevron witness to find that the Ecuador judgment was procured by fraud. Kaplan refused to seat a jury of impartial fact finders, and he refused to consider any evidence of Chevron’s environmental contamination in Ecuador.

But Kaplan’s decision was disproven after evidence emerged that Chevron paid large sums to Alberto Guerra, a former Ecuadorian judge booted from the bench after he admitted taking bribes. Guerra was moved with his family by Chevron to the United States and later admitted lying on the stand after being coached for 53 days by Chevron lawyers headed by Randy Mastro at Gibson Dunn.

Kaplan based his core findings largely on Guerra’s false testimony. And Kaplan remains the only judge in the world to have ruled in favor of Chevron.

Seventeen Ecuador judges, who had access to a fuller evidentiary record than Kaplan, ruled in favor of the affected communities. Twelve judges from Canada, including the country’s entire Supreme Court, have also ruled in favor of the Ecuadorians on various technical issues.

The Ecuador decision confronts Chevron on the brutal human consequences of both its original environmental crimes, which the Court emphasizes were not the result of an accident, but rather of deliberate operational decision-making designed to save money and enrich the company’s shareholders and executives, and the additional offense of its two-decade campaign of distraction and delay.

The Ecuadorian plaintiffs also have picked up several appellate victories in Canadian courts as they attempt to collect Chevron assets in that country to force compliance with the Ecuador judgment.

※ 全文及圖片詳見:

作者

如果有一件事是重要的,如果能為孩子實現一個願望,那就是人類與大自然和諧共存。

於特有生物研究保育中心服務,小鳥和棲地是主要的研究對象。是龜毛的讀者,認為龜毛是探索世界的美德。

延伸閱讀

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

野花如何用多樣性抗氣候變遷 基因研究說分明

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

不能放任蜜蜂死 法國禁五款類尼古丁農藥

摘錄自2018年8月10日中央社報導

法國政府為遏止蜜蜂持續大量死亡,公告自9月1日起禁用五種含類尼古丁的農藥。

法國於2016年實施生物多樣性法規,當時就決定要禁用含類尼古丁(neonicotinoid)的殺蟲劑,這種物質會破壞昆蟲的神經系統,導致蜜蜂等花粉媒介昆蟲迷路及死亡,威脅到生物多樣性和糧食生產。

法國這一波禁用的五種殺蟲劑包括益達胺(imidacloprid)、可尼丁(clothianidin)、賽速安(Thiamethoxam)、賽果培(Thiacloprid)和亞滅培(Acetamiprid)。

法國政府對這類殺蟲劑的禁令比歐盟嚴格。費加洛報(Le Figaro)報導,法國生態部表示,國會正在審議糧食法草案,通過後,應可再增加禁用類尼古丁殺蟲劑的種類。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

美法院裁決 環保署須下令禁用陶斯松

摘錄自2018年8月10日中央社報導

聯邦第九巡迴上訴法院今天(10日)裁決,美國環境保護署(EPA)須在60天內下令禁用陶斯松(chlorpyrifos)。批評人士指出,這種廣泛使用的農藥會傷害兒童和農民。

第九巡迴上訴法院以2票贊成、1票反對的裁決結果,推翻前環保署長普魯特(Scott Pruitt)2017年3月拒絕接受環保團體請願的決定。當時環保團體呼籲,禁止陶斯松用於水果、蔬菜和堅果等糧食作物。

代表第九巡迴上訴法院撰寫裁決書的法官拉柯夫(Jed Rakoff)指出,「科學證據顯示,殘留在糧食上(的陶斯松)會對兒童神經發育造成損害」,但環保署未能提出有力反駁,因此下令環保署須在60天內下令禁用陶斯松。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

SourceTree使用詳解(連接遠程倉庫,克隆,拉取,提交,推送,新建/切換/合併分支,衝突解決)

前言:

  俗話說的好工欲善其事必先利其器,Git分佈式版本控制系統是我們日常開發中不可或缺的。目前市面上比較流行的Git可視化管理工具有SourceTree、Github Desktop、TortoiseGit,綜合網上的一些文章分析和自己的日常開發實踐心得個人比較推薦開發者使用SourceTree,因為SourceTree同時支持Windows和Mac,並且界面十分的精美簡潔,大大的簡化了開發者與代碼庫之間的Git操作方式。該篇文章主要是對日常開發中使用SourceTree可視化管理工具的一些常用操作進行詳細講解。

SourceTree | Github Desktop | TortoiseGit 可視化管理工具對比:

  https://blog.csdn.net/hmllittlekoi/article/details/104504406/

SourceTree介紹和Atlassian賬號註冊和登錄教程:

https://www.cnblogs.com/Can-daydayup/p/13128511.html

連接Gitee or GitHub,獲取代碼:

注意:這裏介紹的是使用SSH協議獲取關聯遠程倉庫的代碼,大家也可以直接使用過HTTPS協議的方式直接輸入賬號密碼獲取關聯代碼!

全面概述Gitee和GitHub生成/添加SSH公鑰:

https://www.cnblogs.com/Can-daydayup/p/13063280.html

在SourceTree中添加SSH密鑰:

工具=>選擇:

   
添加SSH密鑰位置:C:\Users\xxxxx\.ssh\id_rsa.pub:

SSH客戶端選擇OpenSSH:

 

Clone對應託管平台倉庫(以Gitee為例):

打開碼雲,找到自己需要Clone的倉庫!

 

 

SourceTree設置默認工作目錄:

  由上面我們可以發現每次Clone克隆項目的時候,克隆下來的項目默認存儲位置都是在C盤,因此每次都需要我們去選擇項目存放的路徑,作為一個喜歡偷懶的人而言當然不喜歡這種方式啦,因此我們可以設置一個默認的項目存儲位置。

設置SourceTree默認項目目錄:

點擊工具=>選項=>一般=>找到項目目錄設置Clone項目默認存儲的位置  

SourceTree代碼提交:

1.首先切換到需要修改功能代碼所在的分支:

 

 

2.將修改的代碼提交到暫存區:

3.將暫存區中的代碼提交到本地代碼倉庫:

注意:多人同時開發項目的時候,不推薦默認選中立即推送變更到origin/develop,避免一些不必要的麻煩!

 4.代碼拉取更新本地代碼庫,並將代碼推送到遠程倉庫:

 
 勾選需要推送的分支,點擊推送到遠程分支:  
代碼成功推送到遠程代碼庫:

5.在Gitee中查看推送結果:

SourceTree分支切換,新建,合併:

1.分支切換:

雙擊切換:   單擊鼠標右鍵切換:

2.新建分支:

注意:在新建分支時,我們需要在哪個主分支的基礎上新建分支必須先要切換到對應的主分支才能到該主分支上創建分支,如下我們要在master分支上創建一個feature-0613分支:  

3.合併分支:

注意:在合併代碼之前我們都需要將需要合併的分支拉取到最新狀態(**避免覆蓋別人的代碼,或者丟失一些重要文件)!!!!!   在master分支上點擊右鍵,選擇合併feature-0613至當前分支即可進行合併:   分支合併成功:

SourceTree代碼衝突解決:

首先我們需要製造一個提交文件遇到衝突的情景:

在SoureceTree中在Clone一個新項目,命名為pingrixuexilianxi2,如下圖所示:

 

 

我們以項目中的【代碼合併衝突測試.txt】文件為例:   在pingrixuexilianxi2中添加內容,並提交到遠程代碼庫,添加的內容如下:   在pingrixuexilianxi中添加內容,提交代碼(不選擇立即推送變更到origin/master),拉取代碼即會遇到衝突:  

 

 

  衝突文件中的內容:  

直接打開衝突文件手動解決衝突:

由下面的衝突文件中的衝突內容我們了解到:

<<<<<<< HEAD
6月19日 pingrixuexilianxi添加了內容
=======
6月18日 pingrixuexilianxi2修改了這個文件哦
>>>>>>> a8284fd41903c54212d1105a6feb6c57292e07b5

  <<<<<<< HEAD到 =======裏面的【6月19日 pingrixuexilianxi添加了內容】是自己剛才的Commit提交的內容 =======到 >>>>>>> a8284fd41903c54212d1105a6feb6c57292e07b5裏面的【6月18日 pingrixuexilianxi2修改了這個文件哦】是遠程代碼庫更新的內容(即為pingrixuexilianxi2本地代碼庫推送修改內容)。   手動衝突解決方法:

  根據項目需求刪除不需要的代碼就行了,假如都需要的話我們只需要把 <<<<<<< HEAD=======     >>>>>>> a8284fd41903c54212d1105a6feb6c57292e07b5都刪掉衝突就解決了(注意,在項目中最後這些符號都不能存在,否則可能會報異常)。

  最後將衝突文件標記為已解決,提交到遠程倉庫:  

採用外部文本文件對比工具Beyond Compare解決衝突:

SourceTree配置文本文件對比工具Beyond Compare:

工具=>選項=>比較:  

 

使用Beyond Compare解決衝突:

Beyond Compare使用技巧: 官方全面教程: https://www.beyondcompare.cc/jiqiao/   SourceTree打開外部和合併工具:

 

注意:第一次啟動Beynod Compare軟件需要一會時間,請耐心等待:
    Beynod Compare進行衝突合併:   點擊保存文件后關閉Beynod Compare工具,SourceTree中的衝突就解決了,在SourceTree中我們會發現多了一個 .orig 的文件。接着選中那個.orig文件,單擊右鍵 => 移除,最後我們推送到遠程代碼庫即可:  

Sourcetree中的基本名詞說明:

克隆/新建(clone):從遠程倉庫URL加載創建一個與遠程倉庫一樣的本地倉庫。 提交(commit):將暫存區文件上傳到本地代碼倉庫。
推送(push):將本地倉庫同步至遠程倉庫,一般推送(push)前先拉取(pull)一次,確保一致(十分注意:這樣你才能達到和別人最新代碼同步的狀態,同時也能夠規避很多不必要的問題)。 拉取(pull):從遠程倉庫獲取信息並同步至本地倉庫,並且自動執行合併(merge)操作(git pull=git fetch+git merge)。 獲取(fetch):從遠程倉庫獲取信息並同步至本地倉庫。 分支(branch):創建/修改/刪除分枝。 合併(merge):將多個同名文件合併為一個文件,該文件包含多個同名文件的所有內容,相同內容抵消。 貯藏(git stash):保存工作現場。 丟棄(Discard):丟棄更改,恢復文件改動/重置所有改動,即將已暫存的文件丟回未暫存的文件。 標籤(tag):給項目增添標籤。 工作流(Git Flow):團隊工作時,每個人創建屬於自己的分枝(branch),確定無誤后提交到master分支。 終端(terminal):可以輸入git命令行。 每次拉取和推送的時候不用每次輸入密碼的命令行:git config credential.helper osxkeychain sourcetree。 檢出(checkout):切換不同分支。 添加(add):添加文件到緩存區。 移除(remove):移除文件至緩存區。 重置(reset):回到最近添加(add)/提交(commit)狀態。

Git分佈式版本控制器常用命令和使用:

當然作為一個有逼格的程序員, 一些常用的命令我們還是需要了解和掌握的,詳情可參考我之前寫過的文章:

https://www.cnblogs.com/Can-daydayup/p/10134733.html

 

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

八張圖徹底了解JDK8 GC調優秘籍-附PDF下載

目錄

  • 簡介
  • 分代垃圾回收器的內存結構
  • JDK8中可用的GC
  • 打印GC信息
  • 內存調整參數
  • Thread配置
  • 通用GC參數
  • CMS GC
  • G1參數
  • 總結

簡介

JVM的參數有很多很多,根據我的統計JDK8中JVM的參數總共有1853個,正式的參數也有680個。

這麼多參數帶給我們的是對JVM的細粒度的控制,但是並不是所有的參數都需要我們自己去調節的,我們需要關注的是一些最常用的,對性能影響比較大的GC參數即可。

為了更好的讓大家理解JDK8中 GC的調優的秘籍,這裏特意準備了八張圖。在本文的最後,還附帶了一個總結的PDF all in one文檔,大家把PDF下載回去,遇到問題就看兩眼,不美嗎?

分代垃圾回收器的內存結構

為了更好的提升GC的效率,現代的JVM都是採用的分代垃圾回收的策略(ZGC不是)。

java運行時內存可以分為JVM內存和非JVM內存。

JVM內存又可以分為堆內存和非堆內存。

堆內存大家都很熟悉了,YoungGen中的Eden,Survivor和OldGen。

非堆內存中存儲的有thread Stack,Code Cache, NIO Direct Buffers,Metaspace等。

注意這裏的Metaspace元空間是方法區在JDK8的實現,它是在本地內存中分配的。

JDK8中可用的GC

JDK8中到底有哪些可以使用的GC呢?

這裏我們以HotSpot JVM為例,總共可以使用4大GC方式:

其中對於ParallelGC和CMS GC又可以對年輕代和老年代分別設置GC方式。

大家看到上圖可能有一個疑問,Parallel scavenge和Parallel有什麼區別呢?

其實這兩個GC的算法是類似的,Parallel Scavenge收集器也經常稱為“吞吐量優先”收集器,Parallel Scavenge收集器提供了兩個參數用於精確控制吞吐量; -XX:MaxGCPauseMillis:控制最大垃圾收集停頓時間; -XX:GCTimeRatio:設置吞吐量大小。

同時Parallel Scavenge收集器能夠配合自適應調節策略,把內存管理的調優任務交給虛擬機去完成。

JDK8中默認開啟的是ParallelGC。

打印GC信息

如果想研究和理解GC的內部信息,GC信息打印是少不了的:

上圖提供了一些非常有用的GC日誌的控制參數。

內存調整參數

JVM分為Heap區和非Heap區,各個區又有更細的劃分,下面就是調整各個區域大小的參數:

Thread配置

TLAB大家還記得嗎?TLAB的全稱是Thread-Local Allocation Buffers。TLAB是在Eden區間分配的一個一個的連續空間。然後將這些連續的空間分配個各個線程使用。

因為每一個線程都有自己的獨立空間,所以這裏不涉及到同步的概念。

上圖就是TLAB的參數。

通用GC參數

雖然JDK8的GC這麼多,但是他們有一些通用的GC參數:

這裏講解一下Young space tenuring,怎麼翻譯我不是很清楚,這個主要就是指Young space中的對象經過多少次GC之後會被提升到Old space中。

CMS GC

CMS全稱是Concurrent mark sweep。是一個非常非常複雜的GC。

複雜到什麼程度呢?光光是CMS調優的參數都有一百多個!

下圖是常用的CMS的參數。

CMS這裏就不多講了,因為在JDK9之後,CMS就已經被廢棄了。

主要原因是CMS太過複雜,如果要向下兼容需要巨大的工作量,然後就直接被廢棄了。

在JDK9之後,默認的GC是G1。

G1參數

G1收集器是分代的和region化的,也就是整個堆內存被分為一系列大小相等的region。在啟動時,JVM設置region的大小,根據堆大小的不同,region的大小可以在1MB到32MB之間變動,region的數量最多不超過2048個。Eden區、Survivor區、老年代是這些region的邏輯集合,它們並不是連續的。

G1中的垃圾收集過程:年輕代收集和混合收集交替進行,背後有全局的併發標記周期在進行。當老年代分區佔用的空間達到或超過初始閾值,就會觸發併發標記周期。

下圖是G1的調優參數:

總結

上面總共8副圖,我把他們做成了一個PDF,預覽界面大概是這樣子的:

大家可以通過下面的鏈接直接下載PDF版本:

JDK8GC-cheatsheet.pdf

如果遇到問題可以直接拿過來參考。這種東西英文名字應該叫JDK8 GC cheatsheet,翻譯成中文應該就是JDK8 GC調優秘籍!

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/jdk8-gc-cheatsheet/

本文來源:flydean的博客

歡迎關注我的公眾號:程序那些事,更多精彩等着您!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

Newtonsoft 六個超簡單又實用的特性,值得一試 【下篇】

一:講故事

上一篇介紹的 6 個特性從園子里的反饋來看效果不錯,那這一篇就再帶來 6 個特性同大家一起欣賞。

二:特性分析

1. 像弱類型語言一樣解析 json

大家都知道弱類型的語言有很多,如: nodejs,python,php,它們有一個的地方就是處理json,不需要像 強類型語言 那樣還要給它配一個類,什麼意思呢? 就拿下面的 json 說事。


{
  "DisplayName": "新一代算法模型",
  "CustomerType": 1,
  "Report": {
    "TotalCustomerCount": 1000,
    "TotalTradeCount": 50
  },
  "CustomerIDHash": [1,2,3,4,5]
}

這個 json 如果想灌到 C# 中處理,你就得給它定義一個適配的類,就如 初篇 的客戶算法模型類,所以這裏就有了一個需求,能不能不定義類也可以自由解析上面這串 json 呢??? 哈哈,當然是可以的, 反序列化成 Dictionary 即可,就拿提取 Report.TotalCustomerCountCustomerIDHash 這兩個字段演示一下。


        static void Main(string[] args)
        {
            var json = @"{
                           'DisplayName': '新一代算法模型',
                           'CustomerType': 1,
                           'Report': {
                             'TotalCustomerCount': 1000,
                             'TotalTradeCount': 50
                           },
                           'CustomerIDHash': [1,2,3,4,5]
                         }";

            var dict = JsonConvert.DeserializeObject<Dictionary<object, object>>(json);

            var report = dict["Report"] as JObject;
            var totalCustomerCount = report["TotalCustomerCount"];

            Console.WriteLine($"totalCustomerCount={totalCustomerCount}");

            var arr = dict["CustomerIDHash"] as JArray;
            var list = arr.Select(m => m.Value<int>()).ToList();

            Console.WriteLine($"list={string.Join(",", list)}");
        }

2. 如何讓json中的枚舉保持更易讀的字符串型

這句話是什麼意思呢? 默認情況下, SerializeObject 會將 Model 中的 Enum 變成數值型,大家都知道數值型語義性是非常差的,如下代碼所示:


    static void Main(string[] args)
    {
        var model = new ThreadModel() { ThreadStateEnum = System.Threading.ThreadState.Running };

        var json = JsonConvert.SerializeObject(model);

        Console.WriteLine(json);
    }

    class ThreadModel
    {
        public System.Threading.ThreadState ThreadStateEnum { get; set; }
    }

對吧,確實語義特別差,那能不能直接生成 Running 這種字符串形式呢? 當然可以了。。。改造如下:


  var json = JsonConvert.SerializeObject(model, new StringEnumConverter());

這裏可能就有人鑽牛角尖了,能不能部分指定讓枚舉生成 string,其他的生成 int ,沒關係,這也難不倒我,哪裡使用就用 JsonConverter 標記哪裡。。。


        static void Main(string[] args)
        {
            var model = new ThreadModel()
            {
                ThreadStateEnum = System.Threading.ThreadState.Running,
                TaskStatusEnum = TaskStatus.RanToCompletion
            };

            var json = JsonConvert.SerializeObject(model);

            Console.WriteLine(json);
        }

        class ThreadModel
        {
            public System.Threading.ThreadState ThreadStateEnum { get; set; }

            [JsonConverter(typeof(StringEnumConverter))]
            public TaskStatus TaskStatusEnum { get; set; }
        }        

3. 格式化 json 中的時間類型

在 model 轉化成 json 的過程中,總少不了 時間類型,為了讓時間類型 可讀性更高,通常會 格式化為 YYYY年/MM月/dd日 ,那如何實現呢? 很簡單撒,在 JsonConvert 中也是一個 枚舉 幫你搞定。。。


        static void Main(string[] args)
        {
            var json = JsonConvert.SerializeObject(new Order()
            {
                OrderTitle = "女裝大佬",
                Created = DateTime.Now
            }, new JsonSerializerSettings
            {
                DateFormatString = "yyyy年/MM月/dd日",
            });

            Console.WriteLine(json);
        }
        public class Order
        {
            public string OrderTitle { get; set; }
            public DateTime Created { get; set; }
        }   

對了,我記得很早的時候,C# 自帶了一個 JavaScriptSerializer, 也是用來進行 model 轉 json的,但是它會將 datetime 轉成 時間戳,而不是時間字符串形式,如果你因為特殊原因想通過 JsonConvert 將時間生成時間戳的話,也是可以的, 用 DateFormatHandling.MicrosoftDateFormat 枚舉指定一下即可,如下:

4. 對一些常用設置進行全局化

在之前所有演示的特性技巧中都是在 JsonConvert 上指定的,也就是說 100 個 JsonConvert 我就要指定 100 次,那有沒有類似一次指定,整個進程通用呢? 這麼強大的 Newtonsoft 早就支持啦, 就拿上面的 Order 舉例:


        JsonConvert.DefaultSettings = () =>
        {
            var settings = new JsonSerializerSettings
            {
                Formatting = Formatting.Indented
            };
            return settings;
        };

        var order = new Order() { OrderTitle = "女裝大佬", Created = DateTime.Now };

        var json1 = JsonConvert.SerializeObject(order);
        var json2 = JsonConvert.SerializeObject(order);

        Console.WriteLine(json1);
        Console.WriteLine(json2);

可以看到,Formatting.Indented 對兩串 json 都生效了。

5. 如何保證 json 到 model 的嚴謹性 及提取 json 未知字段

有時候我們有這樣的需求,一旦 json 中出現 model 未知的字段,有兩種選擇: 要麼報錯,要麼提取出未知字段,在 Newtonsoft 中默認的情況是忽略,場景大家可以自己找哈。

  • 未知字段報錯

        static void Main(string[] args)
        {
            var json = "{'OrderTitle':'女裝大佬', 'Created':'2020/6/23','Memo':'訂單備註'}";

            var order = JsonConvert.DeserializeObject<Order>(json, new JsonSerializerSettings
            {
                MissingMemberHandling = MissingMemberHandling.Error
            });

            Console.WriteLine(order);
        }

        public class Order
        {
            public string OrderTitle { get; set; }
            public DateTime Created { get; set; }
            public override string ToString()
            {
                return $"OrderTitle={OrderTitle}, Created={Created}";
            }
        }        

  • 提取未知字段

我依稀的記得 WCF 在這種場景下也是使用一個 ExtenstionDataObject 來存儲客戶端傳過來的未知字段,有可能是客戶端的 model 已更新,server端還是舊版本,通常在 json 序列化中也會遇到這種情況,這裏只要使用 JsonExtensionData 特性就可以幫你搞定,在 OnDeserialized 這種AOP方法中進行攔截,如下代碼:


    static void Main(string[] args)
    {
        var json = "{'OrderTitle':'女裝大佬', 'Created':'2020/6/23','Memo':'訂單備註'}";

        var order = JsonConvert.DeserializeObject<Order>(json);

        Console.WriteLine(order);
    }

    public class Order
    {
        public string OrderTitle { get; set; }

        public DateTime Created { get; set; }

        [JsonExtensionData]
        private IDictionary<string, JToken> _additionalData;

        public Order()
        {
            _additionalData = new Dictionary<string, JToken>();
        }

        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            var dict = _additionalData;
        }

        public override string ToString()
        {
            return $"OrderTitle={OrderTitle}, Created={Created}";
        }
    }        

6. 開啟 JsonConvert 詳細日誌功能

有時候在查閱源碼的時候開啟日誌功能更加有利於理解源碼的內部運作,所以這也是一個非常實用的功能,看看如何配置吧。


        static void Main(string[] args)
        {
            var json = "{'OrderTitle':'女裝大佬', 'Created':'2020/6/23','Memo':'訂單備註'}";

            MemoryTraceWriter traceWriter = new MemoryTraceWriter();

            var account = JsonConvert.DeserializeObject<Order>(json, new JsonSerializerSettings
            {
                TraceWriter = traceWriter
            });

            Console.WriteLine(traceWriter.ToString());
        }

        public class Order
        {
            public string OrderTitle { get; set; }

            public DateTime Created { get; set; }

            public override string ToString()
            {
                return $"OrderTitle={OrderTitle}, Created={Created}";
            }
        }

三:總結

嘿嘿,這篇 6 個特性就算說完了, 結合上一篇一共 12 個特性,是不是非常簡單且實用,後面準備給大家帶來一些源碼解讀吧! 希望本篇對您有幫助,謝謝!

如您有更多問題與我互動,掃描下方進來吧~

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

誰再悄咪咪的吃掉異常,我上去就是一 JIO

又到周末了,周更选手申請出站~

這次分享一下上個月碰到的離奇的問題。一個簡單的問題,硬是因為異常被悄咪咪吃掉,過關難度直線提升,導致小黑哥排查一個晚上。

這個美好的晚上,本想着開兩把 LOL 無限火力,在召喚師峽谷來個五殺的~

哎,就這樣沒了啊!我知道,你們一定能理解這種五殺被搶的感覺~

下次,真的,誰再讓我看到悄咪咪的吃掉異常,我真的要上去一 Jio 了!

好了,本文可不是水文,看完本篇文章,你可以學到以下知識點:

  • Arthas 排查技巧
  • 啥是 NoClassDefFoundError
  • Dubbo 異常內部處理方式

好了,同學們,打開小本子,準備記好知識點~

先贊后看養成習慣,微信搜索「程序通事」,關注就完事了

起因

我們有個業務系統,應用之間調用鏈如下所示:

A 應用是業務發生起始應用,在這個應用中將會根據一定規則選擇最後的通訊渠道 C,然後將這個渠道標識傳遞給 B 應用。

B 應用的功能類似網關,這個應用將會根據 A 應用傳遞過來的渠道標識,將會請求路由下發到具體的 C 應用,起到服務路由的功能。

C 應用是與外部應用交互的應用,我們將其稱為渠道通訊機。

假設一次業務中,A 應用根據規則選擇 C2 的渠道標識,然後傳遞給 B 應用。B 應用根據這個標識選擇使用 C2 進行通訊,最後 C2 調用外部應用完成一次業務調用。

上述所有應用都基於 Dubbo 進行遠程通訊,B 應用實現原理在小黑哥之前文章「支付路由系統演進史」中有寫過,感興趣的同學可以查看一下。

介紹完業務的基本情況,現在我們來看下到底發生了啥事。

一次業務需求中,需要改動 C2 應用,這次改動功能點真的很小,很快就完成了。小黑哥想着閑着也是閑着,於是就把之前 C2 應用中打印的日誌中一些沒有脫敏的信息,進行脫敏處理。

由於之前日誌框架脫敏處理存在一些問題,於是就將日誌框架從 Log4j 升級為 LogBack。升級之後,為了防止不同日誌框架中之間的產生衝突,於是使用 IDEA Maven Helper 插件,統一將應用中所有的 Log4j 相關依賴都給排除了。

改動完成之後,將 C2 應用發布到測試環境,再次從 A 應用發起測試, B 應用返回異常提示未找到 C2 應用

B 應用業務代碼類似如下:

public Response pay(Request req) {
    
    try {
        if (!isSupport(req.getChnlCode())) {
            return new Response("ERROR", "未找到相關渠道應用");
        }
        return doPay(req);
    } catch (Exception e) {
        return new Response("ERROR", "未找到相關渠道應用");
    }
}

正常情況下,若是配置存在問題,B 應用將會返回未找到具體渠道,請求也會在 B 應用結束,不會調用到 C2 應用(也沒辦法調用)。

然而此次配置什麼都沒問題, 而且最詭異的是 C2 應用居然收到了請求,並且成功處理了業務請求。

排查問題

由於 B 應用異常處理時,將異常吃掉了,我們沒辦法得知這個過程到底發生了啥事,所以第一要緊的事獲取異常信息。

最簡單的辦法就是,將 B 應用改造一下,加入打印異常日誌。不過當時比較懶,不想改造應用,就想獲取異常信息,於是想到使用 Arthas

Arthas 排錯技巧

Arthas 是Alibaba開源的Java診斷工具,這裏就不再詳細介紹這個工具,主要講下這次排錯用到的命令-watch

watch 命令可以方便觀察指定方的調用情況,可以具體觀察方法的返回值拋出異常入參,另外還可以通過 OGNL表達式查看對應的變量。

這裏我們主要為了查看方法拋出的異常信息,執行命令如下:

watch com.dubbo.example.DemoService doPay -e -x 2 '{params,throwExp}'

上述命令將會在方法異常之後觀察方法的入參以及異常信息。

注意,我們需要查看 doPay 方法,而不是 pay 方法。這是因為 pay方法中我們將異常捕獲,不太可能會拋出異常哦~

異常信息如下所示:

真正引起此次錯誤的異常信息為:

java.lang.NoClassDefFoundError: Could not initialize class xx.xxx.xx.GELogger

由於此次 B 應用不存在改動,所以推測這個異常實際發生在 C2 應用,於是在 C2 應用處再次使用 Arthas watch 命令,同樣觀察到相同的錯誤信息。

NoClassDefFoundError

NoClassDefFound,從名字上我們可以推測是因為類不存在,從而引發的這個錯誤。按照這個思路,我們首先可以簡單查看一下 B 應用中是否存在 GELogger 相關類。

查看 B 應用相關依賴包,從中發現了這個類文件,這說明這個類確實存在。

在 IDEA 反編譯查看 GELogger類相關源碼,從中發現了問題。

private static Logger logger;

static {
    System.out.println("static init");
    logger = Logger.getLogger(NoClassDefFoundErrorTestService.class);
    System.out.println("Logger init success");
}

GELogger存在一個靜態代碼塊,用於初始化一個 org.apache.log4j.Logger日誌類。

然後在上面改動中,全部的 Log4j依賴都被排除了,所以這裏運行時應該會拋出另外一個找到 org.apache.log4j.Logger 錯誤。

執行以下代碼,模擬拋錯過程。

System.out.println("模擬第一次 Error");
try {
    NoClassDefFoundErrorTestService noClassDefFoundErrorTestService=new NoClassDefFoundErrorTestService();
} catch (Throwable e) {
    e.printStackTrace();
}
System.out.println("模擬第二次 Error");
try {
    NoClassDefFoundErrorTestService noClassDefFoundErrorTestService=new NoClassDefFoundErrorTestService();
} catch (Throwable e) {
    e.printStackTrace();
}

異常信息如下所示:

第一次創建 NoClassDefFoundErrorTestService實例時,Java 虛擬機讀取加載時,將會初始化靜態代碼塊時。由於 org.apache.log4j.Logger類不存在,靜態代碼塊執行異常,從而導致類加載失敗。

第二次再創建 NoClassDefFoundErrorTestService 實例時,Java 虛擬機不會再次讀取加載,所以直接返回了以下異常。

java.lang.NoClassDefFoundError: Could not initialize class com.dubbo.example.NoClassDefFoundErrorTestService

找到問題真正原因,解決辦法也很簡單,直接排除 GELogger 所在依賴包。

Dubbo 內部異常處理

雖然問題到此解決了,但是這裏還有一個疑問,為何 C2 應用發生了異常,卻沒有相關錯誤日誌,並且 C2 業務邏輯也正常處理完成。

這就要說到 Dubbo 內部異常錯誤處理方式,上面 GELogger 其實作用在一個 Dubbo 自定義 Filter 中,用來記錄結果,模擬代碼如下:

@Activate(
        group = {"provider", "consumer"}
)
public class ErrorFilter implements Filter {


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        Result result = invoker.invoke(invocation);
        NoClassDefFoundErrorTestService noClassDefFoundErrorTestService=new NoClassDefFoundErrorTestService();
        // 處理業務邏輯
        return result;
    }
}

這個自定義 Filter 中首先執行 invoker 方法,這個方法將會調用真正的業務方法,這就是為什麼 C2 應用邏輯是正常處理完成。

業務方法處理完成之後,然後執行後續邏輯。由於 NoClassDefFoundErrorTestService將會拋出 Error,最終這個 Error,將會在 HeaderExchangeHandler#handleRequest 被捕獲,然後將會把相關異常信息返回給調用 Dubbo 消費者。

而在 Dubbo 消費者接受到服務提供者返回信息之後,將會在 DefaultFuture#doReceived轉化成 RemotingException

RemotingException 最終將會在 FailoverClusterInvoker#doInvoke 轉換成 RpcException返回給業務代碼。

總結

好了,說了這麼多,總結一下本文知識點

  1. 異常捕獲之後,一定要記得打印日誌,並且要記得輸出堆棧信息
  2. 運行時類不存在,將會導致 NoClassDefFoundError,類加載過程失敗,也會導致 NoClassDefFoundError
  3. 對外提供的二方包,最好不要依賴特定日誌框架,如 Log4j,Logback 等,應該使用 Slf4j 框架。

幫助

1、當Dubbo遇上Arthas:排查問題的實踐

2、java.lang.NoClassDefFoundError 的解決方法一例

3、noclassdeffounderror-could-not-initialize-class-error

歡迎關注我的公眾號:程序通事,獲得日常乾貨推送。如果您對我的專題內容感興趣,也可以關注我的博客:studyidea.cn

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

恕我直言你可能真的不會java第5篇:Stream的狀態與并行操作

一、回顧Stream管道流操作

通過前面章節的學習,我們應該明白了Stream管道流的基本操作。我們來回顧一下:

  • 源操作:可以將數組、集合類、行文本文件轉換成管道流Stream進行數據處理
  • 中間操作:對Stream流中的數據進行處理,比如:過濾、數據轉換等等
  • 終端操作:作用就是將Stream管道流轉換為其他的數據類型。這部分我們還沒有講,我們後面章節再介紹。

看下面的腦圖,可以有更清晰的理解:

二、中間操作:有狀態與無狀態

其實在程序員編程中,經常會接觸到“有狀態”,“無狀態”,絕大部分的人都比較蒙。而且在不同的場景下,“狀態”這個詞的含義似乎有所不同。但是“萬變不離其宗”,理解“狀態”這個詞在編程領域的含義,筆者教給大家幾個關鍵點:

  • 狀態通常代表公用數據,有狀態就是有“公用數據”
  • 因為有公用的數據,狀態通常需要額外的存儲。
  • 狀態通常被多人、多用戶、多線程、多次操作,這就涉及到狀態的管理及變更操作。

是不是更蒙了?舉個例子,你就明白了

  • web開發session就是一種狀態,訪問者的多次請求關聯同一個session,這個session需要存儲到內存或者redis。多次請求使用同一個公用的session,這個session就是狀態數據。
  • vue的vuex的store就是一種狀態,首先它是多組件公用的,其次是不同的組件都可以修改它,最後它需要獨立於組件單獨存儲。所以store就是一種狀態。

回到我們的Stream管道流

  • filter與map操作,不需要管道流的前面後面元素相關,所以不需要額外的記錄元素之間的關係。輸入一個元素,獲得一個結果。
  • sorted是排序操作、distinct是去重操作。像這種操作都是和別的元素相關的操作,我自己無法完成整體操作。就像班級點名就是無狀態的,喊到你你就答到就可以了。如果是班級同學按大小個排序,那就不是你自己的事了,你得和周圍的同學比一下身高並記住,你記住的這個身高比較結果就是一種“狀態”。所以這種操作就是有狀態操作。

三、Limit與Skip管道數據截取

List<String> limitN = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
        .limit(2)
        .collect(Collectors.toList());
List<String> skipN = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
        .skip(2)
        .collect(Collectors.toList());
  • limt方法傳入一個整數n,用於截取管道中的前n個元素。經過管道處理之後的數據是:[Monkey, Lion]。
  • skip方法與limit方法的使用相反,用於跳過前n個元素,截取從n到末尾的元素。經過管道處理之後的數據是: [Giraffe, Lemur]

四、Distinct元素去重

我們還可以使用distinct方法對管道中的元素去重,涉及到去重就一定涉及到元素之間的比較,distinct方法時調用Object的equals方法進行對象的比較的,如果你有自己的比較規則,可以重寫equals方法。

List<String> uniqueAnimals = Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")
        .distinct()
        .collect(Collectors.toList());

上面代碼去重之後的結果是: [“Monkey”, “Lion”, “Giraffe”, “Lemur”]

五、Sorted排序

默認的情況下,sorted是按照字母的自然順序進行排序。如下代碼的排序結果是:[Giraffe, Lemur, Lion, Monkey],字數按順序G在L前面,L在M前面。第一位無法區分順序,就比較第二位字母。

List<String> alphabeticOrder = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
        .sorted()
        .collect(Collectors.toList());

排序我們後面還會給大家詳細的講一講,所以這裏暫時只做一個了解。

六、串行、并行與順序

通常情況下,有狀態和無狀態操作不需要我們去關心。除非?:你使用了并行操作。

還是用班級按身高排隊為例:班級有一個人負責排序,這個排序結果最後就會是正確的。那如果有2個、3個人負責按大小個排隊呢?最後可能就亂套了。一個人只能保證自己排序的人的順序,他無法保證其他人的排隊順序。

  • 串行的好處是可以保證順序,但是通常情況下處理速度慢一些
  • 并行的好處是對於元素的處理速度快一些(通常情況下),但是順序無法保證。這可能會導致進行一些有狀態操作的時候,最後得到的不是你想要的結果。
Stream.of("Monkey", "Lion", "Giraffe", "Lemur", "Lion")
        .parallel()
        .forEach(System.out::println);
  • parallel()函數表示對管道中的元素進行并行處理,而不是串行處理。但是這樣就有可能導致管道流中後面的元素先處理,前面的元素后處理,也就是元素的順序無法保證。

如果數據量比較小的情況下,不太能觀察到,數據量大的話,就能觀察到數據順序是無法保證的。

Monkey
Lion
Lemur
Giraffe
Lion

通常情況下,parallel()能夠很好的利用CPU的多核處理器,達到更好的執行效率和性能,建議使用。但是有些特殊的情況下,parallel並不適合:深入了解請看這篇文章:
https://blog.oio.de/2016/01/22/parallel-stream-processing-in-java-8-performance-of-sequential-vs-parallel-stream-processing/
該文章中幾個觀點,說明并行操作的適用場景:

  • 數據源易拆分:從處理性能的角度,parallel()更適合處理ArrayList,而不是LinkedList。因為ArrayList從數據結構上講是基於數組的,可以根據索引很容易的拆分為多個。
  • 適用於無狀態操作:每個元素的計算都不得依賴或影響任何其他元素的計算,的運算場景。
  • 基礎數據源無變化:從文本文件裏面邊讀邊處理的場景,不適合parallel()并行處理。parallel()一開始就容量固定的集合,這樣能夠平均的拆分、同步處理。

歡迎關注我的博客,裏面有很多精品合集

  • 本文轉載註明出處(必須帶連接,不能只轉文字):字母哥博客。

覺得對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創作動力! 。另外,筆者最近一段時間輸出了如下的精品內容,期待您的關注。

  • 《手摸手教你學Spring Boot2.0》
  • 《Spring Security-JWT-OAuth2一本通》
  • 《實戰前後端分離RBAC權限管理系統》
  • 《實戰SpringCloud微服務從青銅到王者》
  • 《VUE深入淺出系列》

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化