文:宋瑞文
本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整
※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!
※教你寫出一流的銷售文案?
※超省錢租車方案
美國加州電動車銷量突破 10 萬輛,在全美電動車交易中,加州占約 40 %。業界指出,銷量增加的主要原因是充電站數量遽增,加上電動車製造商引進更多車款,吸引更多消費者購買。 加州政府希望 2025 年前,電動車數目可達 150 萬輛。目前在美購買電動車的車主可申請聯邦退款 7500 美元,而加州的車主還可另外再獲退款 2500 美元,並享有使用高使用量車道的特權。
本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整
※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!
※教你寫出一流的銷售文案?
※超省錢租車方案
有些時候我們會發現方法名稱都正確匹配,但就是找不到對應請求接口,所以本文我們來深入了解下何時會出現接口請求404的情況。
首先我們創建一個web api應用程序,我們給出如下示例控制器代碼
[ApiController] [Route("[controller]/[action]")] public class WeatherController : ControllerBase { [HttpGet] string Get() { return "Hello World"; } }
當我們進行如上請求時會發現接口請求不到,這是為何呢?細心的你應該可能發現了,對於請求方法是私有,而不是公共的,當我們加上public就可以請求到了接口
[HttpGet("get")] public string Get() { return "Hello World"; }
經過如上示例,那麼對於Action方法的到底要滿足怎樣的定義才能夠不至於請求不到呢?接下來我們看看源碼怎麼講。我們找到DefaultApplicationModelProvider類,在此類中有一個OnProvidersExecuting方法用來構建控制器和Action方法模型,當我們構建完畢所有滿足條件的控制器模型后,緊接着勢必會遍歷控制器模型去獲取對應控制器模型下的Action方法,這裏只截取獲取Action方法片段,源碼如下:
foreach (var controllerType in context.ControllerTypes) { //獲取控制器模型下的Action方法 foreach (var methodInfo in controllerType.AsType().GetMethods()) { var actionModel = CreateActionModel(controllerType, methodInfo); if (actionModel == null) { continue; } actionModel.Controller = controllerModel; controllerModel.Actions.Add(actionModel); } }
上述紅色標記則是創建Action模型的重點,我們繼續往下看到底滿足哪些條件才創建Action模型呢?
protected virtual ActionModel CreateActionModel(TypeInfo typeInfo, MethodInfo methodInfo) { if (typeInfo == null) { throw new ArgumentNullException(nameof(typeInfo)); } if (methodInfo == null) { throw new ArgumentNullException(nameof(methodInfo)); } if (!IsAction(typeInfo, methodInfo)) { return null; } ...... }
到了這個方法裏面,我們找到了如何確定一個方法為Action方法的源頭,由於該方法有點長,這裏我採用文字敘述來作為判斷邏輯,如下:
protected virtual bool IsAction(TypeInfo typeInfo, MethodInfo methodInfo) { //如果有屬性訪問器(無效) //如果有NonAction特性標識無效) //如果重寫Equals(Object), GetHashCode()方法(無效) //如果實現Dispose方法(無效) //如果是靜態方法(無效) //如果是抽象方法(無效) //如果是構造函數(無效) //如果是泛型方法(無效) //必須為公共方法 return methodInfo.IsPublic; }
如上是從方法定義的角度來過濾而獲取Action方法,除此之外,我們請求方法的名稱還可以自定義,比如通過路由、ActionName特性指定,那麼這二者是否存在優先級呢?比如如下示例:
[ApiController] [Route("[controller]/[action]")] public class WeatherController : ControllerBase { [HttpGet] [ActionName("get1")] public string get() { var routeValue = HttpContext.Request.RouteValues.FirstOrDefault(); return routeValue.Value.ToString(); } }
我們可以看到此時將以ActionName特性作為方法名稱。所以在上述過濾方法定義后開始構建方法模型,在此之後還會再做一步操作,那就是查找該方法是否通過ActionName特性標識,若存在則以ActionName特性標識給定的名稱作為請求方法名稱,否則以方法定義名稱為準,源碼如下:
var actionModel = new ActionModel(methodInfo, attributes); AddRange(actionModel.Filters, attributes.OfType<IFilterMetadata>()); var actionName = attributes.OfType<ActionNameAttribute>().FirstOrDefault(); if (actionName?.Name != null) { actionModel.ActionName = actionName.Name; } else { actionModel.ActionName = methodInfo.Name; }
還沒完,若是將路由特性放到Action方法上,如下,此時請求接口應該是weather/get還是weather/get1呢?
[ApiController] public class WeatherController : ControllerBase { [HttpGet] [Route("weather/get")] [ActionName("get1")] public string get() { var routeValue = HttpContext.Request.RouteValues.FirstOrDefault(); return routeValue.Value.ToString(); } }
此時若我們以weather/get1請求將出現404,還是以路由特性模板給定為準進行請求,但最終會將路由上Action方法名稱通過ActionName特性上的名稱賦值給Action模型中的ActionName進行覆蓋,源碼如下,所以上述我們得到的action名稱為get1,,當然這麼做沒有任何實際意義。
public static void AddRouteValues(ControllerActionDescriptor actionDescriptor,ControllerModel controller,ActionModel action) { foreach (var kvp in action.RouteValues) { if (!actionDescriptor.RouteValues.ContainsKey(kvp.Key)) { actionDescriptor.RouteValues.Add(kvp.Key, kvp.Value); } } if (!actionDescriptor.RouteValues.ContainsKey("action")) { actionDescriptor.RouteValues.Add("action", action.ActionName ?? string.Empty); } if (!actionDescriptor.RouteValues.ContainsKey("controller")) { actionDescriptor.RouteValues.Add("controller", controller.ControllerName); } }
本文我們只是單獨針對查找Action方法名稱匹配問題做了進一步的探討,根據源碼分析,對Action方法名稱指定會做3步操作:第一,根據方法定義進行過濾篩選,第二,若方法通過AcionName特性標識則以其所給名稱為準,否則以方法名稱為準,最終賦值給ActionModel上的ActionName屬性,第三,將ActionModel上的ActionName值賦值給路由集合中的鍵Action。
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※帶您來了解什麼是 USB CONNECTOR ?
※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面
※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!
※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化
※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益
※教你寫出一流的銷售文案?
10月10日,中國國務院總理李克強在柏林同德國總理安格拉•默克爾共同主持第三輪中德政府磋商。雙方決定發表《中德合作行動綱要:共塑創新》(下文簡稱《綱要》)。《綱要》共包含86項條文,其中8項提及汽車工業,新能源汽車標準制定與應用推廣成為重中之重。 雙方同意,要繼續加大政府對電動汽車研發、市場開發、基礎設施建設等領域的扶持。雙方商定,給予企業平等享受電動汽車國家扶持和優惠的待遇,並在國家規章、標準制訂中加強協調。雙方將繼續深化中德在電動汽車領域的標準合作。雙方應在充電基建領域就擴建策略和經營模式等議題加強對話。 《綱要》提及,中德兩國應深化電動汽車示範專案和試點城市的交流與合作。在已建立的城市合作框架下,鼓勵中德其他具備條件的城市積極參與。雙方將在電動汽車戰略平臺框架下,探討共建充電基礎設施和電動汽車與智慧電網互通示範項目。它還提出由中國國家發展改革委和德國聯邦環境、自然保護、建築和核安全部牽頭,雙方將繼續深化在電動汽車電池回收利用領域的合作。
本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整
※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!
※教你寫出一流的銷售文案?
※超省錢租車方案
昵稱:目及遠方
課程設計 HumanFramework:
https://github.com/cyclons/HumanFramewo
大四畢業,心血來潮,閑余之際,撰文留念。
遊戲程序員,把這個分成兩塊的話就是,遊戲,程序。
這兩个中,只有一個,遊戲,在我很小的時候就開始接觸,在那個視电子遊戲如电子海洛因,父母抵制到要送孩子去網癮治療所的年代,三年級的我就已經在玩ps2了,周圍的同學還在玩紅警qq大亂斗冒險島飛車的時候,我已經玩高達戰神龍珠古墓麗影,最終導致和周圍同學沒有共同話題。
隨後,按順序入手了nds,psp,xbox360,ps4,可以說從小到大,遊戲沒有停過。
如果說這條職業路上我有什麼超前之處,就是玩遊戲玩得多。
那什麼時候開始想做遊戲了呢?要等到大學。
整個大一的我沉浸在社團幹事與學習中,完全沒有接觸過遊戲編程,學了個譚浩強的c語言,寒假里把下學期的高數學了一遍,然後發現課堂上除了能裝個逼好像也沒什麼特別大用。
直到下半學期的一天夜裡,我在床上思考,以後究竟干什麼比較好,突然一個念頭冒出來,要不去做遊戲吧!這個想法一冒出來,我猛地從床上坐了起來,彷彿一股能量貫穿了全身一般,於是我下定決心買一台電腦,開始我的程序之路。
暑假的時候,搜了好久,終於找到一個感覺靠譜的教程,那就是SIKI,現在已經是遊戲網課的巨頭了,然而當時僅僅只是一個維持了一個小小的公眾號而已,唯一收費的只有一個A計劃,終身費只要400塊。當時選擇的原因有很多,其中最主要的就是大量的免費課程,一個個案例都是自己想要實現的遊戲,總感覺每實現一個,就離成為遊戲製作人更近一步(當時沒有遊戲職業概念)。
剛開始學的階段,可以說我就是個沙雕,半吊子中的半吊子,打字速度20字母/s,不懂語法,大小寫不分,對着視頻敲代碼。(彎路)
後來發現儘管照着視頻做出來了,但仍然不熟練,於是逼迫自己,看視頻不寫代碼,寫代碼不看視頻,偶爾實在不知道怎麼做了,再回去看視頻里怎麼做,一個視頻要看兩三遍。(稍微正了一些)
為了提高自己的打字速度,把手機的鍵盤從9鍵變成26鍵。(有一定作用但不是正道,推薦https://www.keybr.com/)
那時候我還心血來潮,趕VR潮流,在學校里搞起了VR工作室還有VR社團,但剛開始不做技術,是賣硬件的,賣手機紙盒子VR給學生。後來發現潮流過了,硬件沒前途,隨後就想把工作室往技術上轉,當時心裏的想法是邊能學Unity又能搞起一番事業(too young,too simple)。
大二的寒假里,我馬不停蹄,不斷學習SIKI公眾號上的項目案例,每做完一個就信心爆棚,彷彿自己已經是個優秀的遊戲程序員了。之後還在社團里教大家如何做一個AR應用,Unity小遊戲等等。
在大二的暑假里,我還認識了一個朋友,一起做汽車VR噴漆,想通過這個賺錢,但最終失敗了。同時,我發現專業偏硬件,於是我轉專業到計算機學院,開始了第二個大二生活。
後來的日子里,我依然是一有時間就跟着教程學,但彷彿到了一定的瓶頸,感覺做遊戲不就是調調api,用用插件,什麼遊戲都能做出來啊,恰巧當時看到心動在搞獨立營活動,我就立即報名了,這也成為了我第一次的gamejam。
gamejam的感覺呢,怎麼說呢,就好像回家了一樣,裏面各個都是人才,說話又好聽,超喜歡這裏面的~。在活動里,能夠充分體會到周圍人對遊戲的熱愛,精妙的遊戲設計,驚艷的美術,牛逼的程序老哥,主辦方給我們學生還特別優待,給我們免費訂了两天的五星級酒店,還包早餐,可惜都沒怎麼好好享受到,两天可能就住了8個小時不到吧,但整個活動充滿樂趣,給我的第一次gamejam留下了非常棒的印象。
之後便開始積极參加各種jam活動,線上線下到現在快應該有10場,每一次都很有收穫,無論是認識了新的朋友,還是看到了非常驚艷的遊戲,每次都是一場充電之旅。
改變我職業生涯的是一次比賽。
還記得隔壁工作室的老哥問我一句有個AR的比賽來不來參加,我說來。那次比賽是一次hackthon,恰巧有一個單項獎由網易贊助,而且專門設置的AR題材。對我來說,我不了解hackthon,所以就把它當作是一場gamejam,看着周圍一圈985的同學們,壓力山大。
那次我們做了一個AR版本的胡鬧廚房,現在回想起來那代碼寫得就是一坨屎,但遊戲運行非常順暢,沒有bug,從可玩性來看還是挺不錯的,但和以前看的優秀作品比差距還是太遠。聽到主辦方在選出十個演講隊伍中沒有我們的名字時,我們已經收拾好行李,開始回校了。然鵝,這時候主辦方說不要急着走,網易的獎還沒開,我們一路就火急火燎的趕了回去。
由於來得太晚,演講已經開始了一大半,我們幾個人就站在入口的地方聽演講,看着別人的項目,什麼機器學習,區塊鏈,智能小車,各個高大上的不行,彷彿改變未來的技術一樣,而且沒有一個是做遊戲的,我這時候意識到,是不是走錯場了?
等其他獎開完了,才等到網易的負責人上台,大概是這麼說的,“我們在兩支隊伍里徘徊,所以一直沒能下一個定論,但最終我們在完整度上考慮,最終決定把一等獎給9號隊。”
當時整個人都已經懵逼了,周圍隊友興奮的握着我的手,這時候感到一切的努力都是值得的。
獲獎是次要的,最主要的是一等獎附贈一個網易終面機會,作為項目主程,我成功通過了,拿到了實習offer。
這次事件是里程碑,告訴我在這條路上繼續走下去是值得的。
網易實習生活非常豐富,由於是實習生還是在一個偏創新的部門,我和周圍的小夥伴們一起做了非常多好玩有趣的AR遊戲,回來的我也是信心爆棚。
我繼續不斷學習,做項目。但做着做着發現,項目都能跑,但是最終的成品要想改功能,牽一發而動全身,最後改着改着就變成了一坨屎,而那些神乎其神的插件,自己始終停留在會用不會做的階段。
那時候的我非常的慌張,加群,逛知乎,看教程。最後我找到了一本遊戲設計模式,看完之後才知道,原來代碼能這麼寫,好方便啊,這之後代碼又上升了一個階段。
轉眼又一年經過,大三末的我又開始找實習。我本以為我那項目滿滿,經歷豐富的簡歷,一投一個准,做個offer收割機不是問題,然而事實就是,我就是a piece of shit。
算法,數據結構,計算機組成原理,是面試的重中之重,而這裏面每一個都是我的弱點,筆試都通不過。做了幾套面試題之後,我意識到,自己的基礎太弱了。
我開始瘋狂看面經,牛客網,leetcode,uwa也看。最終的出來一個結論,原來我就是個小白。
人貴有自知,知道自己多弱是件好事,至少知道自己要補哪些。這時候就非常感謝恭弘=叶 恭弘大的遊戲程序員學習路線,在書籍的指導下我決定從0開始,從primer cpp開始,從頭重新練,隨着一個個的知識點梳理過去,自己的知識漏洞逐漸補全。
一邊惡補一邊找工作,此時的我就是任人宰割的羔羊,哪家公司要我就去哪裡,大不了過半年,我又是一條好漢。
沒想到,本以為已經涼涼了的騰訊來了電話,那就索性面下去吧,沒想到一路面到了底,拿到了實習offer。。
這次的實習和之前就完全不是一個感覺,正規的大項目,專業的導師,完善的框架,專業的團隊。據說實習留用率低,感覺壓力山大,一邊做着業務,一邊把手邊該看的基礎書在看。
這次依然運氣可以,上岸了。
回校之後,我開始繼續看基礎部分,但發現學習的面越來越廣,尤其是遊戲這塊更是複雜,因此,我逐漸放緩,雖然我的目標是做遊戲,但具體最終是做哪個職位的研究依然不夠清晰,甚至中途還打起了轉行做策劃的念頭。
我設立了第一個目標,搞一個框架。為什麼是這個目標?原因大致如下:
我搜索了很多現有的框架,首先就是學着用,其中就包括strangeIoC,還有MVC等。不得不說,StrangeIoC是新手勸退框架,那一堆東西理念對初級程序員來說就是一頭霧水,明明三行就能實現的東西,為什麼要8個類幾百行實現。
偶然發現了一個QFramework,github千星項目,還有文檔,於是我就開始搞QFramework。
又是一個機會,發現QFramework的作者涼大準備搞事,做一個小班,專心帶學生,12月分期,學生還帶優惠,我轉念一想,當年SIKI還是個小公眾號,現在A計劃永久能賣大幾千,這個車一定要上。
交錢上車后,跟着涼大學,一天兩篇,框架搭建和shader都有涉及。有一說一,雖然是日更的,但是我一般三四天一看,甚至一周一看,剛開始比較勤勞,看得多,有一段時間看着比較累,就斷了一大片。
這裏非常感謝涼大時不時會來私聊,問問學習情況,有沒有遇到什麼困難。我當然也心知肚明,聊完就去補文章了。
正是在這樣的一步步過坎之後,自己的框架意識也逐步建立,共有問題也逐步顯現,C#上欠缺的部分通過中毒篇專欄有了很大的彌補,更重要的是,在未來的路途上有了專業的指導,少走了非常多的彎路,這點真的非常重要。
不知不覺間,一年就過去了,我也幸運的交上了一份畢業設計,學習過程中幾次差點放棄,但看看文章之後覺得這個知識有必要掌握,就一直續到了現在。
本來這篇文章是涼大讓我談談這個框架學習之路,扯了太多自己的東西,這裏就詳細聊聊框架的學習心得:
涼大在小班上非常負責,可以說關心到了每一個成員,內容質量也非常有保證,每每我有“棄坑”的想法時,涼大都會來“善意的提醒”。而我遇到什麼問題時,都能夠得到專業的回答。
大學的前幾年實際上走了不少彎路,如果能夠早期遇到專業的老師來指點的話能少走很多。如果入職一段時間了,職業提升遇到瓶頸,尤其還是從事Unity行業的話,那非常推薦來小班,這裏交流活躍,同行眾多,總有老哥給你指條明路。
在一年結束后,我也最終實現了我的目標,實現了自己的框架——HumanFramework,在大佬眼中應該就是個小不點的存在,但即使這個框架不會成為流行,這個過程也使我對軟件設計的理解更上了一層樓。
最近各種事情算是告一段落,畢業也好,小班也好,工作也好,自己的學生時代也結束了,即將開啟工作時代,由於之前的幾年坎坷奮鬥,加上自己的身體不算強健,現在留下了點胃病,這幾個月里都在養生,時不時看看業內新聞之類的,最近越來越對shader相關的內容感興趣了,之後的主要平台也會變為Unreal,想想也挺有趣的。
在這一年中,學到了很多,尤其是技術分享的重要性,自己也會寫一些文章分享出來,包括HumanFramework的製作過程分享,歡迎來知乎關注我
最終祝願所有讀者在學習的同時身體健康,身體是革命的本錢,有好的身體才有力氣追求更美好的生活。
轉載請註明地址:liangxiegame.com
QFramework 地址:https://github.com/liangxiegame/QFramework
QQ 交流群:623597263
涼鞋的主頁:https://liangxiegame.com/zhuanlan
關注公眾號:liangxiegame 獲取第一時間更新通知及更多的免費內容。
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整
※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!
※教你寫出一流的銷售文案?
※超省錢租車方案
CS-LogN思維導圖:記錄CS基礎 面試題
開源地址:https://github.com/FISHers6/CS-LogN
線程池相關類
能獲取子線程的運行結果
互斥同步(鎖)
非互斥同(原子類)
併發容器
無同步與不可變方案
降低資源消耗
提高響應速度
提高線程的可管理性
corePoolSize、maximumPoolSize、keepAliveTime、workQueue、threadFactory、handler
圖示
線程添加規則
1.如果線程數量小於corePoolSize,即使工作線程處於空閑狀態,也會創建一個新線程來運行新任務,創建方法是使用threadFactory
2.如果線程數量大於corePoolSize但小於maximumPoolSize,則將任務放入隊列
3.如果workQueue隊列已滿,並且線程數量小於maxPoolSize,則開闢一個非核心新線程來運行任務
4.如果隊列已滿,並且線程數大於或等於maxPoolSize,則拒絕該任務,執行handler
圖示(分別與3個參數比較)
常用線程池
newFixedThreadPool
newSingleThreadExecutor
newCachedThreadPool
newScheduledThreadPool
如何設置初始化線程池的大小?
可根據線程池中的線程
處理任務的不同進行分別估計
CPU 密集型任務
IO 密集型任務
使用線程池的注意事項
線程池的狀態
線程池停止
shutdown
shutdownNow
線程池的組成
1.線程池管理器
2.工作線程
3.任務隊列:無界、有界、直接交付隊列
4.任務接口Task
圖示
Executor家族
Executor頂層接口,只有一個execute方法
ExecutorService繼承了Executor,增加了一些新的方法,比如shutdown擁有了初步管理線程池的功能方法
Executors工具類,來創建,類似Collections
圖示
線程池實現任務復用的原理
線程池對線程作了包裝,不需要啟動線程,不需要重複start線程,只是調用已有線程固定數量的線程來跑傳進來的任務run方法
添加工作線程
重複利用線程執行不同的任務
每個 Thread 維護着一個 ThreadLocalMap 的引用;ThreadLocalMap 是 ThreadLocal 的內部類,用 Entry 來進行存儲;key就對應一個個ThreadLocal
get方法:取出當前線程的ThreadLocalMap,然後調用map.getEntry方法,把ThreadLocal作為key參數傳入,取出對應的value
set方法:往 ThreadLocalMap 設置ThreadLocal對應值
initalValue方法:延遲加載,get的時候設置初始化
圖示
value內存泄漏
原因:ThreadLocal 被 ThreadLocalMap 中的 entry 的 key 弱引用。如果 ThreadLocal 沒有被強引用, 那麼 GC 時 Entry 的 key 就會被回收,但是對應的 value 卻不會回收,就會造成內存泄漏
解決方案:每次使用完 ThreadLocal,都調用它的 remove () 方法,清除value數據。
源碼圖示
引入目的
解決Runnable的缺陷
是什麼如何使用
引入目的
常用方法
使用場景
注意點
Callable和Future的關係
Future相當於一個存儲器,它存儲未來call()任務方法的返回值結果
可以用Future.get方法來獲取Callable接口的執行結果,在call()未執行完畢之前沒調用get的線程會被阻塞
線程池傳入Callable,submit返回Future,get獲取值
FutureTask
FutureTask是一種包裝器,可以把Callable轉化成Future和Runnable,它同時實現了二者的接口。所以既可以作為Runnable任務被線程執行,又可以作為Future得到Callable的返回值
圖示
final修飾變量
被final修飾的變量,意味着值不能被修改。
如果變量是對象,那麼對象的引用不能變,但是對象自身的內容依然可以變化。
賦值時機
屬性被聲明為final后,該變量則只能被賦值一次。且一旦被賦值,final的變量就不能再被改變,如論如何也不會變。
區分為3種
final instance variable(類中的final屬性)
final static variable(類中的static final屬性)
final local variable(方法中的final變量)
為什麼規定時機
final修飾方法(構造方法除外)
final修飾類
ABA問題
CAS+自旋,導致自旋時間過長
改進:通過版本號的機制來解決。每次變量更新的時候,版本號加 1,如AtomicStampedReference的compareAndSet ()
簡介
Lock和Synchronized的異同點
相同點
不同點
Lock 有比 synchronized 更精確的線程語義和更好的性能;高級功能
1 實現原理不同
2 靈活性不同
3 等待時是否可以中斷
可見性
悲觀鎖(互斥同步鎖)
思想
實例
缺點
樂觀鎖
思想
實例
優缺點對比
對比
什麼是可重入
可重入的好處
可重入鎖ReentrantLock與非可重入鎖ThreadPoolExecutor的Worker類對比
公平鎖
介紹
優點
缺點
非公平鎖
介紹
優點
缺點
優缺點對比
源碼分析
排他鎖
介紹
共享鎖
介紹
ReentrantReadWriteLock
讀寫鎖的作用
讀寫鎖的規則
一把鎖兩種方式鎖定
讀線程插隊策略(非公平下)
鎖升級
引入場景
策略
適合場景
阻塞鎖
思想
開銷缺陷
自旋鎖
思想
開銷缺陷
源碼分析
atomic包下的類基本都是自旋鎖的實現
AtomicInteger的實現:自旋鎖實現原理是CAS,Atomic調用Unsafe進行自增add的源碼中的do-while循環就是一個自旋操作,使用CAS如果修改過程中遇到其它線程修改導致沒有秀嘎四成功,就在while里死循環,直至修改成功
圖示
適用場景
介紹
使用場景
JDK1.6 后對synchronized鎖的優化
JDK1.6 對鎖的實現引入了大量的優化,如偏向鎖、輕量級鎖、自旋鎖、適應性自旋鎖、鎖消除、鎖粗化等技術來減少鎖操作的開銷。
偏向鎖
輕量級鎖
重量級鎖
自旋鎖
自適應自旋鎖
鎖消除
鎖粗化
寫代碼時的優化
常用方法
實現原理
缺點
引入目的/改進思想
設計思想
集合類歷史
為什麼需要
為什麼不用HashMap
為什麼不用Collection.synchronizedMap
數據結構與併發策略
JDK1.7
JDK1.8
1.7到1.8改變後有哪些優點
注意事項
引入目的
適合場景
讀寫規則
實現原理
缺點
為什麼使用隊列
併發隊列關係圖示
BlockingQueue阻塞隊列
阻塞隊列是局由自動阻塞功能的隊列,線程安全;take方法移除隊頭,若隊列無數據則阻塞直到有數據;put方法插入元素,如果隊列已滿就無法繼續插入則阻塞直到隊列里有了空閑空間
ArrayBlockQueue
LinkedBlockingQueue
PriorityBlockingQueue
SynchronousQueue
DelayQueue
非阻塞隊列
ConcurrentLinkedQueue
選擇合適的隊列
邊界上看
內存上看
吞吐量上看
控制併發流程的工具類,作用是幫助程序員更容易讓線程之間相互配合,來滿足業務邏輯
併發工具類圖示
作用(事件)
常用方法
作用
常用方法
作用
常用方法
作用(線程)
常用方法
Exclusive(獨佔)
Share(共享)
核心三要素
1.sate
2.控制線程搶鎖和配合的FIFO隊列
3.期望協作工具類去實現的“獲取/釋放”等喚醒分配的方法策略
AQS的用法
AQS在CountDownLatch的應用
內部類Sync繼承AQS
1.state表示門閂倒數的count數量,對應getCount方法獲取
2.釋放方法,countDown方法會讓state減1,直到減為0時就喚醒所有線程。countDown方法調用releaseShared,它調用sync實現的tryReleaseShared,其使用CAS+自旋鎖,來實現安全的計數-1
3.阻塞方法,await會調用sync提供的aquireSharedInterruptly方法,當state不等於0時,最終調用LockUpport的park,它利用Unsafe的park,native方法,把線程加入阻塞隊列
總結
AQS在Semphore的應用
state表示信號量允許的剩餘許可數量
tryAcquire方法,判斷信號量大於0就成功獲取,使用CAS+自旋改變state狀態。如果信號量小於0了,再請求時tryAcquireShared返回負數,調用aquireSharedInterruptly方法就進入阻塞隊列
release方法,調用sync實現的releaseShared,會利用AQS去阻塞隊列喚醒一個線程
總結
AQS在ReentrantLock的應用
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整
※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!
※教你寫出一流的銷售文案?
※超省錢租車方案
brokers 中文意思為中間人,在這裏就是指任務隊列本身,接收生產者發來的消息即Task,將任務存入隊列。任務的消費者是Worker,Brokers 就是生產者和消費者存放/拿取產品的地方(隊列)。Celery 扮演生產者和消費者的角色。
常見的 brokers 有 rabbitmq、redis、Zookeeper 等。推薦用Redis或RabbitMQ實現隊列服務。
就是 Celery 中的工作者,執行任務的單元,類似與生產/消費模型中的消費者。它實時監控消息隊列,如果有任務就從隊列中取出任務並執行它。
用於存儲任務的執行結果。隊列中的任務運行完后的結果或者狀態需要被任務發送者知道,那麼就需要一個地方儲存這些結果,就是 Result Stores 了。
常見的 backend 有 redis、Memcached 甚至常用的數據庫都可以。
就是想在隊列中進行的任務,有異步任務和定時任務。一般由用戶、觸發器或其他操作將任務入隊,然後交由 workers 進行處理。
定時任務調度器,根據配置定時將任務發送給Brokers。
1.創建一個celery application 用來定義你的任務列表,創建一個任務文件就叫tasks.py吧。
from celery import Celery
# 配置好celery的backend和broker
app = Celery('task1', backend='redis://127.0.0.1:6379/0', broker='redis://127.0.0.1:6379/0')
#普通函數裝飾為 celery task
@app.task
def add(x, y):
return x + y
如此而來,我們只是定義好了任務函數func函數和worker(celery對象)。worker相當於工作者。
2.啟動Celery Worker來開始監聽並執行任務。broker 我們有了,backend 我們有了,task 我們也有了,現在就該運行 worker 進行工作了,在 tasks.py 所在目錄下運行:
[root@localhost ~]# celery -A tasks worker --loglevel=info # 啟動方法1
[root@localhost ~]# celery -A tasks worker --l debug # 啟動方法2
現在 tasks 這個任務集合的 worker 在進行工作(當然此時broker中還沒有任務,worker此時相當於待命狀態),如果隊列中已經有任務了,就會立即執行。
3.調用任務:要給Worker發送任務,需要調用 delay() 方法。
import time
from tasks import add
# 不要直接add(6, 6),這裏需要用 celery 提供的接口 delay 進行調用
result = add.delay(6, 6)
while not result.ready():
time.sleep(1)
print('task done: {0}'.format(result.get()))
1.celery_config.py:配置文件
from __future__ import absolute_import, unicode_literals
#從python的絕對路徑導入而不是當前的腳本 #在python2和python3做兼容支持的
BROKER_URL = 'redis://127.0.0.1:6379/0'
# 指定結果的接受地址
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0'
2.tasks.py
from __future__ import absolute_import, unicode_literals
#從python的絕對路徑導入而不是當前的腳本 #在python2和python3做兼容支持的
from celery import Celery
# 配置好celery的backend和broker, task1:app的名字。broker
app = Celery('task1', #
broker='redis://127.0.0.1:6379/0', # 消息隊列:連rabbitmq或redis
backend='redis://127.0.0.1:6379/0') # 存儲結果:redis或mongo或其他數據庫
app.config_from_object("celery_config")
app.conf.update( # 給app設置參數
result_expires=3600, # 保存時間為1小時
)
#普通函數裝飾為 celery task
@app.task
def add(x, y):
return x + y
if __name__ == '__main__':
app.start()
3.啟動worker
[root@localhost ~]``# celery -A tasks worker --loglevel=info
4.test.py
import time
from tasks import add
# 不要直接add(4, 4),這裏需要用 celery 提供的接口 delay 進行調用
result = add.delay(6, 6)
print(result.id)
while not result.ready():
time.sleep(1)
print('task done: {0}'.format(result.get()))
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整
※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!
※教你寫出一流的銷售文案?
※超省錢租車方案
意法半導體推出新款車規碳化矽(SiC)二極體,以滿足電動汽車和插電式混合動力車(PHEVs,Plug-in Hybrids)等新能源汽車對車載充電器(OBCs,on-board battery chargers)在有限空間內處理大功率的苛刻要求。
| |
新款二極體採用先進的技術可防止高電流突波燒毀裝置,其過電流保護是額定電流的2.5倍,因此設計人員可選用更小、更經濟實惠且可靠性和效能都不會受到影響的電流更小的二極體。此新碳化矽二極體通過車規產品測試,反向擊穿電壓提高到650V,能滿足設計人員和汽車廠商欲降低電壓補償係數的要求,以確保車載充電半導體元件的標準與瞬間峰值電壓之間有充足的安全邊際。 這次推出的650V二極體包括TO-220AC功率封裝的10A STPSC10H065DY和TO-220AC封裝的12A STPSC12H065DY。此外,TO-220AB封裝的STPSC20H065CTY和TO-247封裝的STPSC20H065CWY是內建2個10A二極體的雙二極體(dual-diode )產品,可最大幅度地提升空間利用度並減少車載充電器的重量。
本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整
※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!
※教你寫出一流的銷售文案?
※超省錢租車方案
![]() |
鴻海於 12 月 22 日公告,以台幣約 24.84 億元入股中國和諧汽車(China Harmony Auto Holding Limited),取得 10.526% 的持股,未來雙方將展開新能源、電動車的通路合作。 和諧汽車為中國進口高級品牌汽車的第二大經銷商,擁有 25 個銷售據點,旗下代理品牌超過 10 個,包括寶馬、勞斯萊斯,MINI、奧迪、法拉利、瑪莎拉蒂等等。 而鴻海集團近來在電動車市場投資與布局也動作頻頻,鴻海集團總裁郭台銘 12 月初率領近 20 人的專家團隊,前往河南首三門峽市的速達電動汽車公司進行實地考察,並駕駛了速達電動車,正式開啟了合作契機。緊接著,富士康與北汽合資電動車租賃公司也傳出獲得中國科技局採用的好消息,成功打入當地電動車租賃市場。 這次,由鴻海主動發布重大訊息,代子公司 Foxconn (Far East) Limited 公告為了與目標公司合作發展新事業,將投資和諧汽車,以港幣約 6.09 億元(約台幣 24.84 億元),每股港幣 4.73 元,取得和諧汽車股份,持股比例將達到 10.526%。 (照片來源:)
本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!
※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線
※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整
※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!
※教你寫出一流的銷售文案?
※超省錢租車方案