怎麼樣才算得上熟悉多線程編程呢?

小小棣


因為你已經會使用多線程了,如果是要熟悉多線程編程,你可以檢查你是否熟悉這幾點:


檢查表

1、線程的內存(內核態和用戶態)消耗,這個對於你使用的語言是否有虛擬機運行時是不一樣的。同時需要了解進程的內存佈局。

2、線程的調度/切換代價、系統調用機制的實現。

3、線程池的設計(是真的設計)和使用。

4、多線程的同步策略,多種級別鎖的實現和性能評估,死鎖問題。輕量鎖或無鎖模式的實現。熟悉常用三方組件提供的接口中的原子操作,自定義分佈式鎖的實現。

5、熟悉異步IO、IO複用的詳細機制和使用。我們平時碰到的大部分應用都是IO密集型的,多線程此時和IO是密不可分的。

6、識別多線程環境(包括隱蔽的多進程協作),能對多線程環境出現的同步和性能問題做出分析和給出解決方案。

語言平臺

如果你需要做基於客戶端的編程,需要了解應用程序模型關於UI線程的設計。

同時基於你使用的語言平臺,你還需要了解相關的基於並行任務編程以及語言本身提供的線程和同步接口,async/await編程模式,並行庫使用等。

我覺得僅僅是熟悉多線程編程,以上應該就差不多了。另外,不同公司在招聘要求中的描述的“熟悉”可能內涵不太一樣,不過你如果上面的檢查表過關了,相信大部分公司都能過這一關。


遷徙de麻雀


從事JAVA開發多年,見證了多線程作為考驗一個人編程能力的重要指標,是如何難到眾多英雄好漢的!

為什麼多線程難以掌握?因為多線程涉及到底層數據處理,同時概念抽象,模型複雜,出現問題難以復現等特性!


先來看下為什麼要使用多線程?我們都知道,單核CPU同一時間只能計算一個線程的數據,而在傳統的網絡編程或者io很容易受到網絡延遲,卡頓等影響導致線程處於阻塞狀態,這個時候的CPU也處於停滯狀態,影響了計算性能的提高!所以引入了多線程技術。。。

單核多線程:在單核CPU中,我們可以在一個線程阻塞的同時,新啟一個線程進行處理,等到這個線程處理完的時候再喚醒其他線程!

多核多線程:多核之間,線程並行處理,單核之內使用上面的模型進行處理!

怎麼樣算是熟悉多線程呢?光是上面的概念可不夠!


1,先解決性能:多線程最根本的需求還是充分"壓榨"CPU資源進行計算,使用多線程避免阻塞,並行計算等是最起碼要會做的,

①,使用繼承Thread和實現Runnable方式實現多線程,掌握線程狀態,喚醒,休眠等方法處理!

②,使用線程池,防止線程頻繁創建和釋放的資源開銷!

③,使用並行處理框架forkjoin和parelleStram處理並行多線程!

④,使用ThreadLocal本地變量避免線程間變量汙染!

⑤,使用future和callable實現線程完成回調!

⑥,會編寫master-workers模型,即一個主線程處理連接,接收任務等,分發給多個執行線程進行處理,這是一個比較高效和經典的模型,值得研究!reactor和netty基於這種模型!


2,再處理安全:多線程因為不可控性,容易引發數據安全問題

①,使用各種鎖,保證數據安全!包括synchonize,readwriterlock(讀鎖共享,寫鎖獨佔),等!

②,使用線程方法實現,線程的順序執行!

③,生產者消費者模型:最常見的模型,保證數據不會重複處理!

④,防止死鎖:順序性的佔有鎖等,避免死鎖!

⑤,使用線程安全的類,concureentMap,hashtable!

⑥,學會樂觀鎖和悲觀鎖編程(之前的文章中有提到過)!

最後,像cyclicBarrier,CountdownLatch的也經常用做倒計數編程等,需要掌握!

JAVA多線程難倒了很多了高手啊,你是被難倒的那一個嗎?有問題歡迎隨時交流,更多的技術分享,敬請關注。。。


謝逅架構


多線程編程的難度是很大的。這是由於多線程程序的問題無法用測試進行檢驗。唯一的辦法是通過邏輯評審。這裡我來分享一下評審多線程程序時使用的思路。

交互邏輯

先說說理論。多線程程序評審有兩個指標:

  • 安全性 共有資源在任何時刻最多隻有一個線程使用。
  • 生存性 所有線程最終都能佔有共有資源,沒有死鎖。

這裡所說的共有資源可以是變量,也可以是一段代碼。為了說明線程控制的基本原則,本文的例子沒有使用編程語言中的多線程控制指令。現在舉例,有很多線程每個線程中都有一個數,你想計算出這些數的合計。用偽代碼表示:

  1. number =from_thread;
  2. summary+=number;

這裡共有資源有兩個number和summary,我們假定有兩個線程,一個在執行第1行,另一個在執行第2行,由於沒有任何限制,這種情況有可能發生,線程不安全。後果是可能漏掉一些數。為了確保安全,考慮建立一個標示,如果標示為零就把標示加一併執行累計,否則,就等待到標示為零。累計完畢後將標示設為零。偽代碼:

  1. while(flag!=0){wait();};
  2. flag++;
  3. number =from_thread;
  4. summary+=number;
  5. flag=0;

檢驗安全性,假定有兩個線程,一個在執行第2行,另一個在執行第3行,我們發現只有flag為零第二個線程才能執行第二行。第一個線程在第三行的時候,flag必不為零。線程是安全的。

接下來檢驗生存性,假定有線程在第1行等待,而flag為零,這個情況不會出現。因此,可生存。

5個哲學家就餐

這是一個十分經典的多線程問題,這個問題網上有很多雷同的答案,大部分都是錯的。當年這個問題也曾困擾微軟的工程師,他們使用了隨機的GUID解決了。但理論上說這個方法並不完美,如果出現了相同的GUID線程就不安全了。雖然概率微乎其微,但畢竟不是零。而Linux也找到了徹底的解法,完美地保證了線程安全。這個問題說來話長。限於篇幅,就說這麼多吧,如有疑問還請包涵。

生活中的例子

交互邏輯並不只存在在編程領域,它和我們的生活息息相關。舉個例子,法律規定遺產繼承要由直系親屬平均分配。其實,這是不安全的。我們用這樣一個家庭進行分析,父母夫妻子共五個人,夫與子出去旅行遭遇空難雙雙死亡。由於無法弄清楚夫與子的死亡順序(兩個線程),夫的遺產(共有資源)繼承上出現了糾紛,若夫先亡,剩下4人每人繼承1/4,子再亡,妻可再繼承子的1/4.共計1/2財產。若子先亡,無財產繼承,夫再亡,剩下三人每人1/3。


分享到:


相關文章: