新聞中心
java程序怎樣寫(xiě)才能使程序健壯、穩(wěn)定、可擴(kuò)展性好
其實(shí),如果是小系統(tǒng),寫(xiě)出健壯,穩(wěn)定,可擴(kuò)展性好的系統(tǒng)或代碼,基本只需要程序員的素養(yǎng)。
撫寧ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)建站的ssl證書(shū)銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書(shū)合作)期待與您的合作!
如果是大系統(tǒng),光有程序員的素養(yǎng)還不夠,整個(gè)系統(tǒng)還要有一個(gè)系統(tǒng)的架構(gòu)思想,和工程思想才能使系統(tǒng)健壯,穩(wěn)定,可擴(kuò)展性好起來(lái)。
當(dāng)然還有,團(tuán)隊(duì)合作,協(xié)調(diào),溝通能力還要好,一般中國(guó)人是做不到這一點(diǎn)的,^_^
.net與Java那個(gè)更具有擴(kuò)展性以及區(qū)別
結(jié)論 C#是一種現(xiàn)代的面向?qū)ο笳Z(yǔ)言。它使程序員快速便捷地創(chuàng)建基于Microsoft .NET平臺(tái)的解決方案。這種框架使C#組件可以方便地轉(zhuǎn)化為XML網(wǎng)絡(luò)服務(wù),從而使任何平臺(tái)的應(yīng)用程序都可以通過(guò)Internet調(diào)用它。 C#增強(qiáng)了開(kāi)發(fā)者的效率,同時(shí)也致力于消除編程中可能導(dǎo)致嚴(yán)重結(jié)果的錯(cuò)誤。C#使C/C++程序員可以快速進(jìn)行網(wǎng)絡(luò)開(kāi)發(fā),同時(shí)也保持了開(kāi)發(fā)者所需要的強(qiáng)大性和靈活性。 Java 簡(jiǎn)介 現(xiàn)代技術(shù)的發(fā)展,尤其是網(wǎng)絡(luò)技術(shù),給現(xiàn)代企業(yè)帶來(lái)了許多新的機(jī)遇和挑戰(zhàn),如改善客戶服務(wù)、全球化和信息檢索等,這些在技術(shù)上反映為信息的獲取、系統(tǒng)管理、系統(tǒng)集成、新技術(shù)的開(kāi)發(fā)、Internet、Intranet等等與商業(yè)的結(jié)合。而這些要求一個(gè)隨處可用的開(kāi)放的結(jié)構(gòu)和在不同的平臺(tái)之間低成本的信息傳遞方式,Java正好滿足這些要求。 Java是由Sun Microsystems公司于1995年5月推出的Java程序設(shè)計(jì)語(yǔ)言(以下簡(jiǎn)稱Java語(yǔ)言)和Java平臺(tái)的總稱。用Java實(shí)現(xiàn)的HotJava瀏覽器(支持Java applet)顯示了Java的魅力:跨平臺(tái)、動(dòng)感的Web、Internet計(jì)算。從此,Java被廣泛接受并推動(dòng)了Web的迅速發(fā)展,常用的瀏覽器現(xiàn)在均支持Java applet。另一方面,Java技術(shù)也不斷更新。 Java平臺(tái)由Java虛擬機(jī)(Java Virtual Machine)和Java 應(yīng)用編程接口(Application Programming Interface、簡(jiǎn)稱API)構(gòu)成。Java 應(yīng)用編程接口為Java應(yīng)用提供了一個(gè)獨(dú)立于操作系統(tǒng)的標(biāo)準(zhǔn)接口,可分為基本部分和擴(kuò)展部分。在硬件或操作系統(tǒng)平臺(tái)上安裝一個(gè)Java平臺(tái)之后,Java應(yīng)用程序就可運(yùn)行。現(xiàn)在Java平臺(tái)已經(jīng)嵌入了幾乎所有的操作系統(tǒng)。這樣Java程序可以只編譯一次,就可以在各種系統(tǒng)中運(yùn)行。Java應(yīng)用編程接口已經(jīng)從1.1.x版發(fā)展到1.2版。目前常用的Java平臺(tái)基于Java1.2。 Java語(yǔ)言是一個(gè)支持網(wǎng)絡(luò)計(jì)算的面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言。Java語(yǔ)言吸收了Smalltalk語(yǔ)言和C++語(yǔ)言的優(yōu)點(diǎn),并增加了其它特性,如支持并發(fā)程序設(shè)計(jì)、網(wǎng)絡(luò)通信、和多媒體數(shù)據(jù)控制等。主要特性如下: 1) Java語(yǔ)言是簡(jiǎn)單的。Java語(yǔ)言的語(yǔ)法與C語(yǔ)言和C++語(yǔ)言很接近,使得大多數(shù)程序員很容易學(xué)習(xí)和使用Java。另一方面,Java丟棄了C++ 中很少使用的、很難理解的、令人迷惑的那些特性,如操作符重載、多繼承、自動(dòng)的強(qiáng)制類型轉(zhuǎn)換。特別地,Java語(yǔ)言不使用指針,并提供了自動(dòng)的廢料收集,使得程序員不必為內(nèi)存管理而擔(dān)憂。 2) Java語(yǔ)言是一個(gè)面向?qū)ο蟮摹ava語(yǔ)言提供類、接口和繼承等原語(yǔ),為了簡(jiǎn)單起見(jiàn),只支持類之間的單繼承,但支持接口之間的多繼承,并支持類與接口之間的實(shí)現(xiàn)機(jī)制(關(guān)鍵字為implements)。Java語(yǔ)言全面支持動(dòng)態(tài)綁定,而C++ 語(yǔ)言只對(duì)虛函數(shù)使用動(dòng)態(tài)綁定。總之,Java語(yǔ)言是一個(gè)純的面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言。 3) Java語(yǔ)言是分布式的。Java語(yǔ)言支持Internet應(yīng)用的開(kāi)發(fā),在基本的Java應(yīng)用編程接口中有一個(gè)網(wǎng)絡(luò)應(yīng)用編程接口(java.net),它提供了用于網(wǎng)絡(luò)應(yīng)用編程的類庫(kù),包括URL、URLConnection、Socket、 ServerSocket等。Java的RMI(遠(yuǎn)程方法激活)機(jī)制也是開(kāi)發(fā)分布式應(yīng)用的重要手段。 4) Java語(yǔ)言是健壯的。Java的強(qiáng)類型機(jī)制、異常處理、廢料的自動(dòng)收集等是Java程序健壯性的重要保證。對(duì)指針的丟棄是Java的明智選擇。Java的安全檢查機(jī)制使得Java更具健壯性。 5) Java語(yǔ)言是安全的。Java通常被用在網(wǎng)絡(luò)環(huán)境中,為此,Java提供了一個(gè)安全機(jī)制以防惡意代碼的攻擊。除了Java語(yǔ)言具有的許多安全特性以外,Java對(duì)通過(guò)網(wǎng)絡(luò)下載的類具有一個(gè)安全防范機(jī)制(類ClassLoader),如分配不同的名字空間以防替代本地的同名類、字節(jié)代碼檢查,并提供安全管理機(jī)制(類SecurityManager)讓Java應(yīng)用設(shè)置安全哨兵。 6) Java語(yǔ)言是體系結(jié)構(gòu)中立的。Java程序(后綴為java的文件)在Java平臺(tái)上被編譯為體系結(jié)構(gòu)中立的字節(jié)碼格式(后綴為class的文件), 然后可以在實(shí)現(xiàn)這個(gè)Java平臺(tái)的任何系統(tǒng)中運(yùn)行。這種途徑適合于異構(gòu)的網(wǎng)絡(luò)環(huán)境和軟件的分發(fā)。 7) Java語(yǔ)言是可移植的。 8) Java語(yǔ)言是解釋型的 9) Java是高性能的。
使用Java構(gòu)造高可擴(kuò)展應(yīng)用
當(dāng)CPU 進(jìn)入多核時(shí)代之后 軟件的性能調(diào)優(yōu)就不再是一件簡(jiǎn)單的事情 沒(méi)有并行化的程序在新的硬件上可能會(huì)運(yùn)行得比從前更慢 當(dāng) CPU 數(shù)目增加的時(shí)候 芯片制造商為了取得最佳的性能/功耗比 降低 CPU 的運(yùn)行頻率是一件非常明智的事情 相比 C/C++ 程序員而言 利用 Java 編寫(xiě)多線程應(yīng)用已經(jīng)簡(jiǎn)單了很多 然而 多線程程序想要達(dá)到高性能仍然不是一件容易的事情 對(duì)于軟件開(kāi)發(fā)人員而言 如果在測(cè)試時(shí)發(fā)現(xiàn)并行程序并不比串行程序快 那不是一件值得驚訝的事情 畢竟 在多核時(shí)代之前 受到廣泛認(rèn)可的并行軟件開(kāi)發(fā)準(zhǔn)則通常過(guò)于簡(jiǎn)單和武斷
在本文中 我們將介紹使提高Java 多線程應(yīng)用性能的一般步驟 通過(guò)運(yùn)用本文提供的一些簡(jiǎn)單規(guī)則 我們就能獲得具有高性能的可擴(kuò)展的應(yīng)用程序
為什么性能沒(méi)有增長(zhǎng)?
多核能帶來(lái)性能的大幅增長(zhǎng) 這很容易通過(guò)簡(jiǎn)單的一些測(cè)試來(lái)觀察到 如果我們寫(xiě)一個(gè)多線程程序 并在每個(gè)線程中對(duì)一個(gè)本地變量進(jìn)行累加 我們可以很容易的看到多核和并行帶來(lái)的成倍的性能提升 這非常容易做到 不是嗎?在 參考資源 里我們給出了一個(gè)例子 然而 與我們的測(cè)試相反 我們很少在實(shí)際軟件應(yīng)用中看到這樣完美的可擴(kuò)展性 阻礙我們獲得完美的可擴(kuò)展性有兩方面的因素存在 首先 我們面臨著理論上的限制 其次軟件開(kāi)發(fā)過(guò)程中也經(jīng)常出現(xiàn)實(shí)現(xiàn)上的問(wèn)題 讓我們看看 圖 中的三條性能曲線
圖 性能曲線
作為追求完美的軟件工程師 我們希望看到隨著線程數(shù)目的增長(zhǎng)程序的性能獲得線性的增長(zhǎng) 也就是圖 中的藍(lán)色直線 而我們最不希望看到的是綠色的曲線 不管投入多少新的 CPU 性能也沒(méi)有絲毫增長(zhǎng) (隨著 CPU 增長(zhǎng)而性能下降的曲線在實(shí)際項(xiàng)目中也存在) 而圖中的紅色線條則說(shuō)明通常的 法則并不適用于可擴(kuò)展性方面 假設(shè)程序中有 % 的計(jì)算只能串行進(jìn)行 那么其擴(kuò)展性曲線如紅線所示 由圖可見(jiàn) 當(dāng) % 的代碼可以完美的并行時(shí) 在 個(gè) CPU 存在的情況下 我們也只能獲得大約 倍的性能 如果任務(wù)中具有無(wú)法并行的部分 那么在現(xiàn)實(shí)世界 我們的性能曲線大致上會(huì)位于圖 中的灰 *** 域
在這篇文章中 我們不會(huì)試圖挑戰(zhàn)理論極限 我們希望能解釋一個(gè) Java 程序員如何能夠盡可能的接近極限 這已經(jīng)不是一個(gè)容易的任務(wù)
是什么造成了糟糕的可擴(kuò)展性?
可擴(kuò)展性糟糕的原因有很多 其中最為顯著的是鎖的濫用 這沒(méi)有辦法 我們就是這樣被教育的 想要多線程安全嗎?那就加一個(gè)鎖吧 想想 Python 中臭名昭著的 Global Intepreter Lock 還有 Java 中的 Collections synchronizedXXXX() 系列方法 跟隨巨人的做法有什么不好嗎?是的 用鎖來(lái)保護(hù)關(guān)鍵區(qū)域非常方便 也較容易保證正確性 然而鎖也意味著只有一個(gè)進(jìn)程能進(jìn)入關(guān)鍵區(qū)域 而其他的進(jìn)程都在等待!如果觀察到 CPU 空閑而軟件執(zhí)行緩慢 那么檢察一下鎖的使用是一個(gè)明智的做法
對(duì)于 Java 程序而言 Performance Inspector 中的 Java Lock Monitor 是一個(gè)不錯(cuò)的開(kāi)源工具
[NextPage]
對(duì)一個(gè)多線程應(yīng)用進(jìn)行調(diào)優(yōu)
下面 我們將提供一個(gè)例子程序并演示如何在多核平臺(tái)上獲得更好的可擴(kuò)展性 這個(gè)例子程序演示了一個(gè)假想的日志服務(wù)器 它接收來(lái)自多個(gè)源的日志信息并將其統(tǒng)一保存到文件系統(tǒng)中 為了簡(jiǎn)單起見(jiàn) 我們的例子代碼中不包含任何的網(wǎng)絡(luò)相關(guān)代碼 Main() 函數(shù)將啟動(dòng)多個(gè)線程來(lái)發(fā)送日志信息到日志服務(wù)器中 對(duì)于性急的讀者 讓我們先看看調(diào)優(yōu)的結(jié)果
圖 日至服務(wù)器調(diào)優(yōu)結(jié)果
在上圖中 藍(lán)色的曲線是一個(gè)基于 Lock 的老式日志服務(wù)器 而綠色的曲線是我們進(jìn)行了性能調(diào)優(yōu)之后的日志服務(wù)器 可以看到 LogServerBad 的性能隨線程數(shù)目的增加變化很小 而 LogServerGood 的性能則隨著線程數(shù)目的增加而線性增長(zhǎng) 如果不介意使用第三方的庫(kù)的話 那么來(lái)自 Project KunMing 的 LockFreeQueue 可以進(jìn)一步提供更好的可擴(kuò)展性
圖 使用 Lock free 的數(shù)據(jù)結(jié)構(gòu)
在上圖中 第三條曲線表示用 LockFreeQueue 替換標(biāo)準(zhǔn)庫(kù)中的 ConcurrentLinkedQueue 之后的性能曲線 可以看到 如果線程數(shù)目較少時(shí) 兩條曲線差別不大 但是單線程數(shù)目增大到一定程度之后 Lock Free 的數(shù)據(jù)結(jié)構(gòu)具有明顯的優(yōu)勢(shì)
在下文中 將介紹在上述例子中使用的可以幫助我們創(chuàng)建高可擴(kuò)展 Java 應(yīng)用的工具和技巧
[NextPage]
使用 JLM 分析應(yīng)用程序
JLM 提供了 Java 應(yīng)用和 JVM 中鎖持有時(shí)間和沖突統(tǒng)計(jì) 具體提供以下功能
對(duì)沖突的鎖進(jìn)行計(jì)數(shù)
成功獲得鎖的次數(shù)
遞歸鎖的次數(shù)
申請(qǐng)鎖的線程被阻塞等待的次數(shù)
鎖被持有的累計(jì)時(shí)間 對(duì)于支持 Tier Spin Locking 的平臺(tái) 還可以獲得以下信息 :
請(qǐng)求線程在內(nèi)層(spin loop)請(qǐng)求鎖的次數(shù)
請(qǐng)求線程在外層(thread yield loop)請(qǐng)求鎖的次數(shù)
使用 rtdriver 工具收集更詳細(xì)的信息
jlmlitestart 僅收集計(jì)數(shù)器
jlmstart 僅收集計(jì)數(shù)器和持有時(shí)間統(tǒng)計(jì)
jlmstop 停止數(shù)據(jù)收集
jlmdump 打印數(shù)據(jù)收集并繼續(xù)收集過(guò)程
從鎖持有時(shí)間中去除垃圾收集(Garbage Collection GC)的時(shí)間
GC 時(shí)間從 GC 周期中所有被持有的鎖的持有時(shí)間中去除
使用 AtomicInteger 進(jìn)行計(jì)數(shù)
通常 在我們實(shí)現(xiàn)多線程使用的計(jì)數(shù)器或隨機(jī)數(shù)生成器時(shí) 會(huì)使用鎖來(lái)保護(hù)共享變量 這樣做的弊端是如果鎖競(jìng)爭(zhēng)的太厲害 會(huì)損害吞吐量 因?yàn)楦?jìng)爭(zhēng)的同步非常昂貴
volatile 變量雖然可以使用比同步更低的成本存儲(chǔ)共享變量 但它只可以保證其他線程能夠立即看到對(duì) volatile 變量的寫(xiě)入 無(wú)法保證讀 修改 寫(xiě)的原子性 因此 volatile 變量無(wú)法用來(lái)實(shí)現(xiàn)正確的計(jì)數(shù)器和隨機(jī)數(shù)生成器
從 JDK 開(kāi)始 ncurrent atomic 包中引入了原子變量 包括 AtomicInteger AtomicLong AtomicBoolean 以及數(shù)組 AtomicIntergerArray AtomicLongArray 原子變量保證了 ++ —— += = 等操作的原子性 利用這些數(shù)據(jù)結(jié)構(gòu) 您可以實(shí)現(xiàn)更高效的計(jì)數(shù)器和隨機(jī)數(shù)生成器
加入輕量級(jí)的線程池—— Executor
大多數(shù)并發(fā)應(yīng)用程序是以執(zhí)行任務(wù)(task)為基本單位進(jìn)行管理的 通常情況下 我們會(huì)為每個(gè)任務(wù)單獨(dú)創(chuàng)建一個(gè)線程來(lái)執(zhí)行 這樣會(huì)帶來(lái)兩個(gè)問(wèn)題 一 大量的線程( )會(huì)消耗系統(tǒng)資源 使線程調(diào)度的開(kāi)銷變大 引起性能下降 二 對(duì)于生命周期短暫的任務(wù) 頻繁地創(chuàng)建和消亡線程并不是明智的選擇 因?yàn)閯?chuàng)建和消亡線程的開(kāi)銷可能會(huì)大于使用多線程帶來(lái)的性能好處
一種更加合理的使用多線程的方法是使用線程池(Thread Pool) ncurrent 提供了一個(gè)靈活的線程池實(shí)現(xiàn) Executor 框架 這個(gè)框架可以用于異步任務(wù)執(zhí)行 而且支持很多不同類型的任務(wù)執(zhí)行策略 它還為任務(wù)提交和任務(wù)執(zhí)行之間的解耦提供了標(biāo)準(zhǔn)的方法 為使用 Runnable 描述任務(wù)提供了通用的方式 Executor 的實(shí)現(xiàn)還提供了對(duì)生命周期的支持和 hook 函數(shù) 可以添加如統(tǒng)計(jì)收集 應(yīng)用程序管理機(jī)制和監(jiān)視器等擴(kuò)展
在線程池中執(zhí)行任務(wù)線程 可以重用已存在的線程 免除創(chuàng)建新的線程 這樣可以在處理多個(gè)任務(wù)時(shí)減少線程創(chuàng)建 消亡的開(kāi)銷 同時(shí) 在任務(wù)到達(dá)時(shí) 工作線程通常已經(jīng)存在 用于創(chuàng)建線程的等待時(shí)間不會(huì)延遲任務(wù)的執(zhí)行 因此提高了響應(yīng)性 通過(guò)適當(dāng)?shù)恼{(diào)整線程池的大小 在得到足夠多的線程以保持處理器忙碌的同時(shí) 還可以防止過(guò)多的線程相互競(jìng)爭(zhēng)資源 導(dǎo)致應(yīng)用程序在線程管理上耗費(fèi)過(guò)多的資源
Executor 默認(rèn)提供了一些有用的預(yù)設(shè)線程池 可以通過(guò)調(diào)用 Executors 的靜態(tài)工廠方法來(lái)創(chuàng)建
newFixedThreadPool 提供一個(gè)具有最大線程個(gè)數(shù)限制的線程池 newCachedThreadPool 提供一個(gè)沒(méi)有最大線程個(gè)數(shù)限制的線程池 newSingleThreadExecutor 提供一個(gè)單線程的線程池 保證任務(wù)按照任務(wù)隊(duì)列說(shuō)規(guī)定的順序(FIFO LIFO 優(yōu)先級(jí))執(zhí)行 newScheduledThreadPool 提供一個(gè)具有最大線程個(gè)數(shù)限制線程池 并支持定時(shí)以及周期性的任務(wù)執(zhí)行
使用并發(fā)數(shù)據(jù)結(jié)構(gòu)
Collection 框架曾為 Java 程序員帶來(lái)了很多方便 但在多核時(shí)代 Collection 框架變得有些不大適應(yīng) 多線程之間的共享數(shù)據(jù)總是存放在數(shù)據(jù)結(jié)構(gòu)之中 如 Map Stack Queue List Set 等 Collection 框架中的這些數(shù)據(jù)結(jié)構(gòu)在默認(rèn)情況下并不是多線程安全的 也就是說(shuō)這些數(shù)據(jù)結(jié)構(gòu)并不能安全地被多個(gè)線程同時(shí)訪問(wèn) JDK 通過(guò)提供 SynchronizedCollection 為這些類提供一層線程安全的接口 它是用 synchronized 關(guān)鍵字實(shí)現(xiàn)的 相當(dāng)于為整個(gè)數(shù)據(jù)結(jié)構(gòu)加上一把全局鎖保證線程安全
ncurrent 中提供了更加高效 collection 如 ConcurrentHashMap/Set ConcurrentLinkedQueue ConcurrentSkipListMap/Set CopyOnWriteArrayList/Set 這些數(shù)據(jù)結(jié)構(gòu)是為多線程并發(fā)訪問(wèn)而設(shè)計(jì)的 使用了細(xì)粒度的鎖和新的 Lock free 算法 除了在多線程條件下具有更高的性能 還提供了如 put if absent 這樣適合并發(fā)應(yīng)用的原子函數(shù)
[NextPage]
其他一些需要考慮的因素
不要給內(nèi)存系統(tǒng)太大的壓力
如果線程執(zhí)行過(guò)程中需要分配內(nèi)存 這在 Java 中通常不會(huì)造成問(wèn)題 現(xiàn)代的 JVM 是高度優(yōu)化的 它通常為每個(gè)線程保留一塊 Buffer 這樣在分配內(nèi)存時(shí) 只要 buffer 沒(méi)有用光 那么就不需要和全局的堆打交道 而本地 buffer 分配完畢之后 JVM 將不得不到全局堆中分配內(nèi)存 這樣通常會(huì)帶來(lái)嚴(yán)重的可擴(kuò)展性的降低 另外 給 GC 帶來(lái)的壓力也會(huì)進(jìn)一步降低程序的可擴(kuò)展性 盡管我們有并行的 GC 但其可擴(kuò)展性通常并不理想 如果一個(gè)循環(huán)執(zhí)行的程序在每次執(zhí)行中都需要分配臨時(shí)對(duì)象 那么我們可以考慮利用 ThreadLocal 和 SoftReference 這樣的技術(shù)來(lái)減少內(nèi)存的分配
使用 ThreadLocal
ThreadLocal 類能夠被用來(lái)保存線程私有的狀態(tài)信息 對(duì)于某些應(yīng)用非常方便 通常來(lái)講 它對(duì)可擴(kuò)展性有正面的影響 它能為各個(gè)線程提供一個(gè)線程私有的變量 因而多個(gè)線程之間無(wú)須同步 需要注意的是在 JDK 之前 ThreadLocal 有著相當(dāng)?shù)托У膶?shí)現(xiàn) 如果需要在 JDK 或更老的版本上使用 ThreadLocal 需要慎重評(píng)估其對(duì)性能的影響 類似的 目前 JDK 中的 ReentrantReadWriteLock 的實(shí)現(xiàn)也相當(dāng)?shù)托?如果想利用讀鎖之間不互斥的特性來(lái)提高可擴(kuò)展性 同樣需要進(jìn)行 profile 來(lái)確認(rèn)其適用程度
鎖的粒度很重要
粗粒度的全局鎖在保證線程安全的同時(shí) 也會(huì)損害應(yīng)用的性能 仔細(xì)考慮鎖的粒度在構(gòu)建高可擴(kuò)展 Java 應(yīng)用時(shí)非常重要 當(dāng) CPU 個(gè)數(shù)和線程數(shù)較少時(shí) 全局鎖并不會(huì)引起激烈的競(jìng)爭(zhēng) 因此獲得一個(gè)鎖的代價(jià)很小(JVM 對(duì)這種情況進(jìn)行了優(yōu)化) 隨著 CPU 個(gè)數(shù)和線程數(shù)增多 對(duì)全局鎖的競(jìng)爭(zhēng)越來(lái)越激烈 除了一個(gè)獲得鎖的 CPU 可以繼續(xù)工作外 其他試圖獲得該鎖的 CPU 都只能閑置等待 導(dǎo)致整個(gè)系統(tǒng)的 CPU 利用率過(guò)低 系統(tǒng)性能不能得到充分利用 當(dāng)我們遇到一個(gè)競(jìng)爭(zhēng)激烈的全局鎖時(shí) 可以嘗試將鎖劃分為多個(gè)細(xì)粒度鎖 每一個(gè)細(xì)粒度鎖保護(hù)一部分共享資源 通過(guò)減小鎖的粒度 可以降低該鎖的競(jìng)爭(zhēng)程度 ncurrent ConcurrentHashMap 就通過(guò)使用細(xì)粒度鎖 提高 HashMap 在多線程應(yīng)用中的性能 在 ConcurrentHashMap 中 默認(rèn)構(gòu)造函數(shù)使用 個(gè)鎖保護(hù)整個(gè) Hash Map 用戶可以通過(guò)參數(shù)設(shè)定使用上千個(gè)鎖 這樣相當(dāng)于將整個(gè) Hash Map 劃分為上千個(gè)碎片 每個(gè)碎片使用一個(gè)鎖進(jìn)行保護(hù)
結(jié)論
通過(guò)選擇一種合適的 profile 工具 檢查 profile 結(jié)果中的熱點(diǎn)區(qū)域 使用適合多線程訪問(wèn)的數(shù)據(jù)結(jié)構(gòu) 線程池 細(xì)粒度鎖減小熱點(diǎn)區(qū)域 并重復(fù)此過(guò)程不斷提高應(yīng)用的可擴(kuò)展性
lishixinzhi/Article/program/Java/gj/201311/27639
java低代碼開(kāi)發(fā)平臺(tái)有哪些?
java低代碼開(kāi)發(fā)平臺(tái),能快速開(kāi)發(fā),節(jié)省人工成本,提高開(kāi)發(fā)效率。
國(guó)內(nèi)快速開(kāi)發(fā)平臺(tái)如目前流行的低代碼快速開(kāi)發(fā)平臺(tái)(如有天翎 ?,普元,天縱,等廠家)myApps微服務(wù)架構(gòu),多租戶模式,門(mén)戶集成,單點(diǎn)登錄,移動(dòng)端(企業(yè)微信,釘釘,APP),功能模板都是可視化配置(如表單引擎,視圖引擎,流程引擎,報(bào)表引擎,像操作word或Excel,擴(kuò)展性強(qiáng),提供源代碼,支持國(guó)產(chǎn)數(shù)據(jù)庫(kù),操作系統(tǒng)((瀚高,達(dá)夢(mèng),統(tǒng)信,中標(biāo)麒麟等)如天翎java平臺(tái)后端核心框架:Spring MVC+SpringBoot2.X,視圖框架:Spring MVC,緩存框架:Ehcache+Redis,持久層框架:Hibernate+JDBC+File System Serilizable,安全框架:Spring security+antisamyt等
java中多態(tài)如何實(shí)現(xiàn)程序的可擴(kuò)展性
C++中:用基類的引用指定派生類的對(duì)象,然后通過(guò)該引用來(lái)訪問(wèn)派生類的方法,這是基本的多態(tài)形式。(Java中用的接口的概念)
這樣的好處是,程序的已知流程在沒(méi)有派生類的時(shí)候就可以寫(xiě)好,以后要有新的功能,只要再寫(xiě)個(gè)派生類就可以了。舉個(gè)例子,在電腦上顯示圖片,基本上要有讀文件,解析文件,顯示圖形三個(gè)步驟,這些步驟可以寫(xiě)在基類中,然后具體的如何讀文件,如何解析文件,如何顯示,就交給派生類去做。
java編寫(xiě)具有可擴(kuò)展性的圖形參數(shù)計(jì)算程序,計(jì)算周長(zhǎng)和面積
創(chuàng)建一個(gè)接口Shape,內(nèi)有g(shù)et周長(zhǎng)()和get面積()兩個(gè)方法,然后創(chuàng)建類矩形、圓形、三角形什么的implements Shape,實(shí)現(xiàn)那兩個(gè)方法就行了
當(dāng)前文章:java擴(kuò)展性強(qiáng)的代碼 java擴(kuò)展類
轉(zhuǎn)載源于:http://ef60e0e.cn/article/hjehes.html