程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 多核時代考驗Java代碼編寫習慣

多核時代考驗Java代碼編寫習慣

編輯:關於JAVA

我承認,這個標題是有點誇大其辭了。顯然正確的Java還是有的,甚至有不少,但是我感覺這相對於Java代碼的總量來說可能只是微不足道的一小部分。為什麼我會有這麼極端的一個說法呢?

這又回到了Java內存模型問題上,以及對於在代碼運行時“計算機”中發生了些什麼的不符合人們直覺思維的。為了避免有人說我對Java有偏見,我得先聲明,我非常清楚Java是第一種試圖提供可靠,可用,跨平台的多線程編程環境的語言。這是很難做到的。在初試嘗試時一些細節問題上出現了重大錯誤也應該不會有人覺得奇怪。那此問題到JSR-133就被解決了,從Java 5開始就被廣泛部署開來。

但是,即使用的較新的Java環境,帶有更寬松、可預見性更強的的內存模型,還是會有很多錯誤發生,而我們也粗心大意根本沒有注意這些問題。這是怎麼回事呢?必讀書目《Java並發編程實踐》(Java Concurrency in Practice,51CTO讀書頻道有這本書的試讀。後面我還會提到這本書)的作者Brian Goetz說得好:

“……由於常用的處理器(Intel和Sparc)都提供比JVM所需更強的存儲能力,即使許多開發人員經常錯誤地使用同步和volatile,但是因為部署的處理器架構能提供很強的存儲能力,所以得以僥幸避免出錯。”

這面這段引用是他這個月所作的講話的一個摘要。我真希望我能去聽講。隨著越來越多的電腦擁有了多個多核處理器,我們以前依賴的內存行為開始消失了,我們這些Java開發人員也從以前那種僥幸的、錯誤的方式中醒悟過來。

編輯推薦:哪種語言將統治多核時代 再看函數式語言特性

這一切的失敗仿佛早就注定。我們學習Java的許多方式,不管是通過示例程序,課堂教學或是書籍,都導致了這些錯誤。所以我們有了根深蒂固的錯誤而且危險的思維習慣,並且還導致我們以一種錯誤的方式來思考程序……這也導致了在部署過程中發生一些不起眼的錯誤,這些錯誤日後極難被找出和修復。

難道只有多線程程序中才有這個問題?還有,專家所寫的代碼中難道不會少一點這些問題嗎?不是這樣的。想想使用Swing圖形界面工具包開發的程序。或者,更常見的,運行在Servlet容器中的一個服務端程序。在這種兩種情況下,你都被迫進入了多線程環境。

我想我們大多數人都對如何處理競爭條件和死鎖以及如何用同步解決問題有好的辦法,特別是當涉及到多個變量時。這些是很難學會的,但是長期以來好的例子,還有大環境的影響,讓我們在理解和運用多線程編程上走上正軌。

即便如此,像雙檢測鎖定這樣一些爛方法的存在說明我們的理解還有問題。而我們的東西在什麼地方散架也只是一個明不明顯的問題。如果不合適地使用同步或volatile來聲明變量,即使是很穩定不變的的值也有可能在其它線程中完全看不到。我們所理解的一個像共享池一樣的主存實在是過於簡化了,這導致我們對於代碼將有哪些行為和哪些是安全的會作出錯誤的判斷。

最近我們的一個產品在用戶多核處理器上的站點出現了問題,這讓我對這一點更加刻骨銘心。這個問題我們自己沒法重現,在測試中也沒出現過,但是通過禁用一個處理器,這個問題就可以解決。此後不久,我的一位同事根據他在《Java並發編程實踐》中所讀到的一些內容為當地的Java用戶組作了一次演講,這讓我想起來我一直想讀這本書,我也該抽時間讀讀這本書了。

我也這樣做了。這還真是讓我大開眼界。它明確了一些我以前在JavaOne以及網上聽說過的,卻從來沒有融會貫通的一些問題。它讓我更明白了Java代碼的真正意義,以及如何寫安全的 Java代碼。我們團隊一直一起閱讀這本書,有好幾個星期都在午餐後討論這本書,它讓我們能修正我們的Java代碼,使其在多處理器上也正常運行。多處理器曾經很昂貴並且不穩定,但現在正成為主流。所以這並不能說是為時尚早——我們還希望能在之前就深入了解這些呢。將所學的這些靈活運用,讓我們建立起寫無誤代碼的信心還需要一些時間,但至少我們走上了正軌。

每個寫Java的人都應該讀讀這本書,為了他們自己,還有他們的用戶。Brian Goetz為IBM developerWorks所寫的兩篇文章(一、二)可以作為我這裡所提到的這些問題的一個總結,但是那並不能代替擁有大量分析、建議還有范例的《Java並發編程實踐》。

不過,即使我們在發現這些問題上變得很厲害了,這問題也還是不那麼容易解決。這也促使我思考並認真看看Scala,它是一門較新的語言,可以在 JVM中和其它的語言一起運行,並通過更可靠和可信的函數式編程平台解決棘手的並行編程部分,函數式編程裡大多數都是不可變的對象。Scala那種無共享,基於角色的消息傳遞並行機制是源於運行在JVM外的Erlang語言,這種機制很有前景。但是,這又是今後的另一個話題了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved